Rex W. Douglass
Data Availability and Interpolation over Time
#test <- lhs_long %>% group_by(dataset, gid, geonameid, wikidata_id, date_asdate) %>% summarize(n=n())
all_na <- function(x) any(!is.na(x)) #https://intellipaat.com/community/12999/remove-columns-from-dataframe-where-all-values-are-na
#bing looks off by a day from the other ones
lhs_wide_qcode <- lhs_long %>%
filter(!is.na(wikidata_id) & !is.na(date_asdate)) %>%
group_by(gid, geonameid, wikidata_id, date_asdate) %>% mutate(confirmed_var=var(confirmed, na.rm=T), deaths_var=var(deaths, na.rm=T)) %>% ungroup() %>%
dplyr::select(dataset, gid, geonameid, wikidata_id, date_asdate,confirmed, deaths, tested_samples, tested_people) %>%
group_by(dataset, gid, geonameid, wikidata_id, date_asdate) %>% summarise_if(is.numeric,max,na.rm=T) %>% ungroup() %>% #this is a hack, we should have dupes within datasets
pivot_wider(names_from = dataset, values_from = c(confirmed, deaths, tested_samples, tested_people) ) %>%
mutate_if(is.numeric, list(~na_if(abs(.), Inf))) %>% #https://stackoverflow.com/questions/12188509/cleaning-inf-values-from-an-r-dataframe
select_if(all_na)
dim(lhs_wide_qcode) #82,157 82k place/day observations
length(unique(lhs_wide_qcode$wikidata_id)) #3697 #almost 4k
test <- lhs_wide_qcode %>% dplyr::select(starts_with("confirmed")) %>% distinct()
#cor(test, use="pairwise.complete.obs")
lhs_long_median <- lhs_long %>% group_by(gid, geonameid, wikidata_id, date_asdate) %>% summarize_if(is.numeric, median, na.rm=T) %>% dplyr::select(-ends_with("_fd")) %>% #we take the median across observations
mutate(CFR=deaths/confirmed)
#dim(lhs_long_median)
#summary(lhs_long_median)
Here we do the actual interpolation. For each individual location-dataset, we fit a piecewise linear model over time, and then use that to average over day to day noise and interpolate between observations. Because this is in log space, the slope of that line is the day on day percent increase in the count. We finish by fitting a piecewise intercept model to those slopes to get a single daily estimate of how much the count is increasing. Datasets are able to disagree in lots of different ways and we still recover a correct rate of change.
Interpolation of Counts
To each individual dataset-location series, we fit a piecewise linear trend. Each segment is required to have at least 3 observations, but otherwise we make no other constraints. This allows us to flexibly fit linear segments as well as tight curves. We also allow for structural breaks where the series stops, has a structural shift up or down because say a change in reporting rules, but other then otherwise continues as normal. We take the linear trend fit as our best estimate at each point. This averages over day to day noise, e.g. under reporting on the weekend. It also allows us to interpolate between observations where there is missingness in the series but we have reasonable beliefs the true measure continued linearly between the observed points.
#we need to parallelize this code and see what's loudly throwing
#Error in chol.default(J12) :
# the leading minor of order 1 is not positive definite
dataset_places <- lhs_long_clean %>% dplyr::select(dataset_gid_geonameid_wikidata_id) %>% distinct() %>% pull(dataset_gid_geonameid_wikidata_id)
library(party)
temp_list1 <- list()
options(error = expression(NULL))
sink(NULL)
zz <- file("messages.txt", open = "wt")
sink(zz)
suppressMessages(
for(q in dataset_places ){
#try({
temp <- NULL
temp <- lhs_long_clean %>%
filter(dataset_gid_geonameid_wikidata_id %in% q) %>%
arrange(date_asdate) %>%
mutate(confirmed_log=log(confirmed)) %>%
mutate(deaths_log=log(deaths)) %>%
mutate(tested_people_log=log(tested_people)) %>%
mutate(tested_samples_log=log(tested_samples))
if(nrow(temp)==0){next()}
temp <- temp %>% expand(dataset, gid_geonameid_wikidata_id, gid, geonameid,wikidata_id, date_asdate=min(date_asdate):max(date_asdate) %>% as_date() ) %>%
full_join(temp) %>%
mutate(date_asnumeric= as.numeric(date_asdate) ) %>%
arrange(date_asnumeric) %>%
mutate(confirmed_nonmissing_count = (!is.na(confirmed)) %>% cumsum() ) %>%
mutate(deaths_nonmissing_count = (!is.na(deaths)) %>% cumsum() ) %>%
mutate(tested_people_nonmissing_count = (!is.na(tested_people)) %>% cumsum() ) %>%
mutate(tested_samples_nonmissing_count = (!is.na(tested_samples)) %>% cumsum() ) %>%
arrange(-date_asnumeric) %>%
mutate(confirmed_nonmissing_count_reversed = (!is.na(confirmed)) %>% cumsum() ) %>%
mutate(deaths_nonmissing_count_reversed = (!is.na(deaths)) %>% cumsum() ) %>%
mutate(tested_people_nonmissing_count_reversed = (!is.na(tested_people)) %>% cumsum() ) %>%
mutate(tested_samples_nonmissing_count_reversed = (!is.na(tested_samples)) %>% cumsum() ) %>%
arrange(date_asdate)
tryCatch({
if(sum(!is.na(temp$confirmed_log))>=3){ #need at least 3 points
tree_confirmed <- party::mob(confirmed_log ~ 1 + date_asnumeric | date_asnumeric , control = mob_control(minsplit = 3, alpha=.2), data = temp, model = linearModel) # + I(date_asnumeric^2)
temp$confirmed_log_y_hat <- predict( tree_confirmed, newdata=temp , type = c("response") )
temp$confirmed_log_group_number <- predict( tree_confirmed, newdata=temp , type = c("node"))
temp <- temp %>%
mutate(confirmed_log_y_hat =ifelse(confirmed_nonmissing_count>0 & confirmed_nonmissing_count_reversed>0,confirmed_log_y_hat,NA)) %>% #only interpolate within the observed data, never before or after
mutate(confirmed_log_group_number=ifelse(confirmed_nonmissing_count>0 & confirmed_nonmissing_count_reversed>0,confirmed_log_group_number,NA)) %>% #only interpolate within the observed data, never before or after
group_by(confirmed_log_group_number) %>%
arrange(date_asnumeric) %>%
mutate(confirmed_log_y_hat_slope=tsibble::difference(confirmed_log_y_hat)) %>%
fill(confirmed_log_y_hat_slope, .direction="up") %>%
ungroup() %>%
mutate(confirmed_log_y_hat_percent_change = round((exp(confirmed_log_y_hat_slope)-1)*100,2)) %>%
mutate(confirmed_log_y_hat=ifelse(confirmed_log_y_hat<0,NA, confirmed_log_y_hat))
}
}, error = function(e) {}, silent=TRUE)
tryCatch({
if(sum(!is.na(temp$deaths_log))>=3){ #need at least 3 points
tree_deaths <- party::mob(deaths_log ~ 1 + date_asnumeric | date_asnumeric , control = mob_control(minsplit = 3, alpha=.2), data = temp, model = linearModel) # + I(date_asnumeric^2)
temp$deaths_log_y_hat <- predict( tree_deaths, newdata=temp , type = c("response") )
temp$deaths_log_group_number <- predict( tree_deaths, newdata=temp , type = c("node"))
temp <- temp %>%
mutate(deaths_log_y_hat=ifelse(deaths_nonmissing_count>0 & deaths_nonmissing_count_reversed>0,deaths_log_y_hat,NA)) %>% #only interpolate within the observed data, never before
mutate(deaths_log_group_number=ifelse(deaths_nonmissing_count>0 & deaths_nonmissing_count_reversed>0,deaths_log_group_number,NA)) %>% #only interpolate within the observed data, never before
group_by(deaths_log_group_number) %>%
arrange(date_asnumeric) %>%
mutate(deaths_log_y_hat_slope=tsibble::difference(deaths_log_y_hat)) %>%
fill(deaths_log_y_hat_slope, .direction="up") %>%
ungroup() %>%
mutate(deaths_log_y_hat_percent_change = round((exp(deaths_log_y_hat_slope)-1)*100,2)) %>%
mutate(deaths_log_y_hat=ifelse(deaths_log_y_hat<0,NA, deaths_log_y_hat)) #reject any where the prediction is less than 1 full case
}
}, error = function(e) {}, silent=TRUE)
tryCatch({
if(sum(!is.na(temp$tested_people_log))>=3){ #need at least 3 points
tree_tested_people <- party::mob(tested_people_log ~ 1 + date_asnumeric | date_asnumeric , control = mob_control(minsplit = 3, alpha=.2), data = temp, model = linearModel) # + I(date_asnumeric^2)
temp$tested_people_log_y_hat <- predict( tree_tested_people, newdata=temp , type = c("response") )
temp$tested_people_log_group_number <- predict( tree_tested_people, newdata=temp , type = c("node"))
temp <- temp %>%
mutate(tested_people_log_y_hat=ifelse(tested_people_nonmissing_count>0 & tested_people_nonmissing_count_reversed>0,tested_people_log_y_hat,NA)) %>% #only interpolate within the observed data, never before
mutate(tested_people_log_group_number=ifelse(tested_people_nonmissing_count>0 & tested_people_nonmissing_count_reversed>0,tested_people_log_group_number,NA)) %>% #only interpolate within the observed data, never before
group_by(tested_people_log_group_number) %>%
arrange(date_asnumeric) %>%
mutate(tested_people_log_y_hat_slope=tsibble::difference(tested_people_log_y_hat)) %>%
fill(tested_people_log_y_hat_slope, .direction="up") %>% ungroup() %>%
mutate(tested_people_log_y_hat_percent_change = round((exp(tested_people_log_y_hat_slope)-1)*100,2)) %>%
mutate(tested_people_log_y_hat=ifelse(tested_people_log_y_hat<0,NA, tested_people_log_y_hat)) #reject any where the prediction is less than 1 full case
}
}, error = function(e) {}, silent=TRUE)
temp_list1[[q ]] <- temp
#})
}
)
sink(NULL)
lhs_long_clean_imputed1 <- bind_rows(temp_list1)
dim(lhs_long_clean_imputed1) #500,786 #bigger because we're interpolating now
#rt1 <- rpart(formula = confirmed_log_y_hat_percent_change ~ date_asnumeric, data=test)
#interpolated = data.frame(date_asnumeric=min(test$date_asnumeric):max(test$date_asnumeric) )
#interpolated$confirmed_log_y_hat_percent_change_y_hat <- predict(rt1, newdata=interpolated)
#interpolated$date_asdate <- as.Date(interpolated$date_asnumeric)
places <- lhs_long_clean %>% dplyr::select(gid_geonameid_wikidata_id) %>% distinct() %>% pull(gid_geonameid_wikidata_id)
library(rpart)
minsplit=6
minbucket=3
temp_list2 <- list()
for(q in places ){
print(q)
temp <- lhs_long_clean_imputed1 %>%
filter(gid_geonameid_wikidata_id %in% q) %>%
arrange(date_asnumeric)
tryCatch({
rt1 <- rpart::rpart(formula = confirmed_log_y_hat_percent_change ~ date_asnumeric,
data=temp %>% filter(!is.na(confirmed_log)), #to keep from fitting to interpolate slopes that are out of domain and usually wrong, require confirmed to not be missing or na
control = rpart.control(minsplit = minsplit, minbucket=minbucket))
temp$confirmed_log_y_hat_percent_change_y_hat <- predict(rt1, newdata=temp) #this prediction helpfully tries to impute backwards even before there are any day in any series
#We need to nuke it if no data exist
temp <- temp %>%
group_by(date_asdate) %>%
mutate( confirmed_nonmissing_count_datasets=sum(confirmed_nonmissing_count>0,na.rm=T) ) %>%
mutate( confirmed_nonmissing_count_datasets_reversed=sum(confirmed_nonmissing_count_reversed>0,na.rm=T) ) %>%
mutate(confirmed_log_y_hat_percent_change_y_hat=ifelse(confirmed_nonmissing_count_datasets>0 & confirmed_nonmissing_count_datasets_reversed>0,confirmed_log_y_hat_percent_change_y_hat,NA)) %>%
ungroup()
}, error = function(e) {})
tryCatch({
rt2 <- rpart::rpart(formula = deaths_log_y_hat_percent_change ~ date_asnumeric,
data=temp %>% filter(!is.na(deaths_log)),
control = rpart.control(minsplit = minsplit, minbucket=minbucket))
temp$deaths_log_y_hat_percent_change_y_hat <- predict(rt2, newdata=temp)
temp <- temp %>%
group_by(date_asdate) %>%
mutate( deaths_nonmissing_count_datasets=sum(deaths_nonmissing_count>0,na.rm=T) ) %>%
mutate( deaths_nonmissing_count_datasets_reversed=sum(deaths_nonmissing_count_reversed>0,na.rm=T) ) %>%
mutate(deaths_log_y_hat_percent_change_y_hat=ifelse(deaths_nonmissing_count_datasets>0 & deaths_nonmissing_count_datasets_reversed>0,deaths_log_y_hat_percent_change_y_hat,NA)) %>%
ungroup()
}, error = function(e) {})
tryCatch({
rt3 <- rpart::rpart(formula = tested_people_log_y_hat_percent_change ~ date_asnumeric,
data=temp %>% filter(!is.na(tested_people_log)),
control = rpart.control(minsplit = minsplit, minbucket=minbucket))
temp$tested_people_log_y_hat_percent_change_y_hat <- predict(rt3, newdata=temp, control = rpart.control(minsplit = minsplit, minbucket=minbucket))
temp <- temp %>%
group_by(date_asdate) %>%
mutate( tested_people_nonmissing_count_datasets=sum(tested_people_nonmissing_count>0,na.rm=T) ) %>%
mutate( tested_people_nonmissing_count_datasets_reversed=sum(tested_people_nonmissing_count_reversed>0,na.rm=T) ) %>%
mutate(tested_people_log_y_hat_percent_change_y_hat=ifelse(tested_people_nonmissing_count_datasets>0 & tested_people_nonmissing_count_datasets_reversed>0,tested_people_log_y_hat_percent_change_y_hat,NA)) %>%
ungroup()
}, error = function(e) {})
temp_list2[[q ]] <- temp
}
lhs_long_clean_imputed2 <- bind_rows(temp_list2)
lhs_long_clean_imputed <- lhs_long_clean_imputed2
dim(lhs_long_clean_imputed) #629,493 #419910 #413475 #408,369 #we lose anywithout q codes here
saveRDS(lhs_long_clean_imputed, "/media/skynet2/905884f0-7546-4273-9061-12a790830beb/rwd_github_private/NESScovid19/data_temp/lhs_long_clean_imputed.Rds")
Examples
China
#China
#"Q148"
test <- lhs_long_clean_imputed %>%
mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q148") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation0 <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 Confirmed") + facet_wrap(~dataset )
Data on China shows variation across datasets for when they start measuring. Only two observe the very beginning of the outbreak. All of the datasets show a discontinuity where reporting standards must have changed. Our method attempts to bridge that gap in 3 of the series but not two others.
p_interpolation0

Italy
#Italy
#"Q38"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q38") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation1 <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 Confirmed") + facet_wrap(~dataset )
Italy likewise shows variation in the start of recording across datasets. There’s also variation in the initial sparcity. Wikipedia is strangely missing data in the middle. Our method linearly interpolates into that space in a way in a way we probably don’t want.
p_interpolation1

Italy
#US
#"Q30"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q30") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation2 <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("US Q30 Confirmed") + facet_wrap(~dataset )
p_interpolation2

New York State
#US
#"Q30"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q1384") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation3 <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("New York State Q1384 Confirmed") + facet_wrap(~dataset )
p_interpolation3

New York City (by county)
nyt has it just by city, it doesn’t break it down by the boroughs. But because gadm doesn’t do cities we don’t assign it a qcode.
usafacts has it as New York County which is New York County (Manhattan)
#Brooklyn (Q18419)
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q855974") %>% #no hits?
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation4a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bronx County (Q855974)") + facet_wrap(~dataset ) + guides( color = FALSE)
#Queens County, New York Q5142559
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q5142559") %>% #no hits?
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation4b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Queens County, New York Q5142559") + facet_wrap(~dataset ) + guides( color = FALSE)
#Brooklyn is aparently Kings County Q11980692
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q11980692") %>% #no hits?
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation4c <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Brooklyn is Kings County Q11980692") + facet_wrap(~dataset ) + guides( color = FALSE)
# Manhattan is New York County Q500416
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q500416") %>% #no hits?
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation4d <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Manhattan is New York County Q500416") + facet_wrap(~dataset ) + guides( color = FALSE)
#Staten Island is richmond county Q11997784
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q11997784") %>% #no hits?
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p_interpolation4e <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Staten Island Richmond County Q11997784") + facet_wrap(~dataset ) + guides( color = FALSE)
Note that CSSE is conflating all of New York City with Manhattan/New York County, Bing is too I think
p_interpolation4a + p_interpolation4b + p_interpolation4c + p_interpolation4d + p_interpolation4e

Plots by Countries
library(data.table)
geonames <- fread("/media/skynet2/905884f0-7546-4273-9061-12a790830beb/rwd_github_private/NESScovid19/data_temp/allCountries.txt", sep="\t") %>% mutate_if(is.numeric,as.character) %>% mutate_if(is.factor,as.character)
|--------------------------------------------------|
|==================================================|
|--------------------------------------------------|
|==================================================|
Found and resolved improper quoting out-of-sample. First healed line 522433: <<8436127 "Baki-Pilsen" Brewery "Baki-Pilsen" Brewery 40.32864 49.78044 P PPLL AZ 0 -25 Asia/Baku 2012-12-17>>. If the fields are not quoted (e.g. field separator does not appear within any field), try quote="" to avoid this warning.
dim(geonames) #12,006,426
[1] 12006426 19
geonames_small <- geonames %>% dplyr::select(geonameid=V1, name_text=V2) %>% inner_join( lhs_long_clean_imputed %>% dplyr::select(geonameid) %>% distinct() )
Joining, by = "geonameid"
dim(geonames_small)
[1] 4108 2
Confirmed
p_confirmed_by_country <- lhs_long_clean_imputed %>%
filter(!gid %>% str_detect("_") ) %>%
left_join(geonames_small ) %>% mutate(name_text %>% as.factor()) %>%
mutate(group=paste(gid_geonameid_wikidata_id,confirmed_log_group_number)) %>%
ggplot() +
#geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Confirmed (log) by Country") + facet_wrap(~name_text ) + guides( color = FALSE) +
theme(
strip.background = element_blank()
, strip.text.x = element_blank()
)
p_confirmed_by_country

Deaths
p_deaths_by_country <- lhs_long_clean_imputed %>%
filter(!gid %>% str_detect("_") ) %>%
left_join(geonames_small ) %>% mutate(name_text %>% as.factor()) %>%
mutate(group=paste(gid_geonameid_wikidata_id,confirmed_log_group_number)) %>%
ggplot() +
#geom_point( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Deaths (log) by Country") + facet_wrap(~name_text ) + guides( color = FALSE) +
theme(
strip.background = element_blank()
, strip.text.x = element_blank()
)
p_deaths_by_country

Tests
p_tested_people_by_country <- lhs_long_clean_imputed %>%
filter(!gid %>% str_detect("_") ) %>%
left_join(geonames_small ) %>% mutate(name_text %>% as.factor()) %>%
mutate(group=paste(gid_geonameid_wikidata_id,confirmed_log_group_number)) %>%
ggplot() +
#geom_point( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Tests (log) by Country") + facet_wrap(~name_text ) + guides( color = FALSE) +
theme(
strip.background = element_blank()
, strip.text.x = element_blank()
)
p_tested_people_by_country

Interpolation of Rate of Change
Plot Confirmed Curves for Select Locations
library(patchwork)
lhs_long_clean_imputed <- readRDS( "/media/skynet2/905884f0-7546-4273-9061-12a790830beb/rwd_github_private/NESScovid19/data_temp/lhs_long_clean_imputed.Rds")
dim(lhs_long_clean_imputed) #45,609 #337043
#we want the colors to be consistent by dataset too btw
#####
#USA Q30
#bp_temp <- breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=temp_df %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q30"))
#confirmed_log_y_hat_percent_change=fitted.values(bp_temp)
test <- lhs_long_clean_imputed %>%
mutate(group=paste(dataset,wikidata_id,confirmed_log_group_number)) %>%
filter(wikidata_id=="Q30") %>%
arrange(date_asdate) %>%
mutate(date_asnumeric = date_asdate %>% as.numeric() )
#rt1 <- rpart(formula = confirmed_log_y_hat_percent_change ~ date_asnumeric, data=test)
#interpolated = data.frame(date_asnumeric=min(test$date_asnumeric):max(test$date_asnumeric) )
#interpolated$confirmed_log_y_hat_percent_change_y_hat <- predict(rt1, newdata=interpolated)
#interpolated$date_asdate <- as.Date(interpolated$date_asnumeric)
p0a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 Confirmed") # + facet_wrap(~dataset)
p0b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3 ) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black" ) +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 Confirmed") # + facet_wrap(~dataset)+ ylab("Daily Percent Change Confirmed")
#p0a / p0b
#####
#China Q148
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_group_number)) %>% filter(wikidata_id=="Q148") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
p1a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 Confirmed")
p1b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 Confirmed")+ ylab("Daily Percent Change Confirmed")
#p1a / p1b
#India
#"Q668"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q668") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p2a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 Confirmed")
p2b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 Confirmed")+ ylab("Daily Percent Change Confirmed")
#p2a / p2b
#Italy
#"Q38"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q38") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p4a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 Confirmed")
p4b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 Confirmed")+ ylab("Daily Percent Change Confirmed")
#p4a / p4b
#South Korea
#"Q884"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q884") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p5a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 Confirmed")
p5b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 Confirmed") + ylab("Daily Percent Change Confirmed")
#p5a / p5b
(p0a + p1a + p2a ) / (p0b + p1b + p2b )

( p4a + p5a) / ( p4b + p5b)

test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q1439") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p0a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Texas Q1439 Confirmed")
p0b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Texas Q1439 Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#Bexar
#"Q16861"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q16861") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p1a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 Confirmed")
p1b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#California
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q99") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p2a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("California Q99 Confirmed")
p2b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("California Q99 Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#San Diego County (Q108143)
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q108143") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p3a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("San Diego County (Q108143) Confirmed")
p3b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("San Diego County (Q108143) Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#Florida (Q812)
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q812") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p4a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Florida (Q812) Confirmed")
p4b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Florida (Q812) Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#St. Lucie County (Q494564)
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,confirmed_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q494564") %>%
mutate(group=paste(dataset, wikidata_id,confirmed_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( confirmed_log_y_hat_percent_change = breakpoints(formula=confirmed_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p5a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=confirmed_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("St. Lucie County (Q494564) Confirmed")
p5b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=confirmed_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=confirmed_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=confirmed_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("St. Lucie County (Q494564) Confirmed") + ylim(0,100)+ ylab("Daily Percent Change Confirmed")
#Not counting slopes that were interpolated out of domain fixed california's plot
( p0a + p1a ) / ( p0b + p1b )

( p2a + p3a ) / ( p2b + p3b )

( p4a + p5a) / ( p4b + p5b)

Plot Death Curves for Select Locations
Show how interpolation works on deaths
test <- lhs_long_clean_imputed %>%
mutate(group=paste(dataset,wikidata_id,deaths_log_group_number)) %>%
filter(wikidata_id=="Q30") %>%
arrange(date_asdate) %>%
mutate(date_asnumeric = date_asdate %>% as.numeric() )
p0a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 Deaths") # + facet_wrap(~dataset)
p0b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3 ) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black" ) +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 Deaths") + ylab("Daily Percent Change Deaths") # + facet_wrap(~dataset)
#p0a / p0b
#####
#China Q148
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,deaths_log_group_number)) %>% filter(wikidata_id=="Q148") %>%
mutate(group=paste(dataset, wikidata_id,deaths_log_group_number)) %>%
arrange(date_asdate) #%>%
p1a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 Deaths")
p1b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 Deaths")+ ylab("Daily Percent Change Deaths")
#p1a / p1b
#India
#"Q668"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,deaths_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q668") %>%
mutate(group=paste(dataset, wikidata_id,deaths_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( deaths_log_y_hat_percent_change = breakpoints(formula=deaths_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p2a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 Deaths")
p2b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 Deaths")+ ylab("Daily Percent Change Deaths")
#p2a / p2b
#Bexar
#"Q16861"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,deaths_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q16861") %>%
mutate(group=paste(dataset, wikidata_id,deaths_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( deaths_log_y_hat_percent_change = breakpoints(formula=deaths_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p3a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 Deaths")
p3b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 Deaths") + ylim(0,100)+ ylab("Daily Percent Change Deaths")
#p3a / p3b
#Italy
#"Q38"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,deaths_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q38") %>%
mutate(group=paste(dataset, wikidata_id,deaths_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( deaths_log_y_hat_percent_change = breakpoints(formula=deaths_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p4a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 Deaths")
p4b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 Deaths")+ ylab("Daily Percent Change Deaths")
#p4a / p4b
#South Korea
#"Q884"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,deaths_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q884") %>%
mutate(group=paste(dataset, wikidata_id,deaths_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( deaths_log_y_hat_percent_change = breakpoints(formula=deaths_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p5a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=deaths_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 Deaths")
p5b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=deaths_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=deaths_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=deaths_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=deaths_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 Deaths") + ylab("Daily Percent Change Deaths")
#p5a / p5b
I need to fix this, USA has a fraction of a death
Note the discontinuity in Chin when they added those 1k deaths to the total
India deaths is broken, we shouldn’t be interpolating a rate before we think the number is greater than 0
(p0a + p1a + p2a ) / (p0b + p1b + p2b )

(p3a + p4a + p5a) / (p3b + p4b + p5b)

Plot Testing Curves for Select Locations
Show how interpolation works on tested
US is an example where we interpolated past our available data. Shouldn’t do that either!
test <- lhs_long_clean_imputed %>%
mutate(group=paste(dataset,wikidata_id,tested_people_log_group_number)) %>%
filter(wikidata_id=="Q30") %>%
arrange(date_asdate) %>%
mutate(date_asnumeric = date_asdate %>% as.numeric() )
p0a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 Tested") #+ facet_wrap(~dataset)
p0b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3 ) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black" ) +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("USA Q30 tested_people") + ylab("Daily Percent Change tested_people") # + facet_wrap(~dataset)
#p0a / p0b
#####
#China Q148
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,tested_people_log_group_number)) %>% filter(wikidata_id=="Q148") %>%
mutate(group=paste(dataset, wikidata_id,tested_people_log_group_number)) %>%
arrange(date_asdate) #%>%
p1a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 tested_people")
p1b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("China Q148 tested_people")+ ylab("Daily Percent Change tested_people")
#p1a / p1b
#India
#"Q668"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,tested_people_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q668") %>%
mutate(group=paste(dataset, wikidata_id,tested_people_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( tested_people_log_y_hat_percent_change = breakpoints(formula=tested_people_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p2a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 tested_people")
p2b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("India Q668 tested_people")+ ylab("Daily Percent Change tested_people")
#p2a / p2b
#Bexar
#"Q16861"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,tested_people_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q16861") %>%
mutate(group=paste(dataset, wikidata_id,tested_people_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( tested_people_log_y_hat_percent_change = breakpoints(formula=tested_people_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p3a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 tested_people")
p3b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Bexar County Q16861 tested_people") + ylim(0,100)+ ylab("Daily Percent Change tested_people")
#p3a / p3b
#Italy
#"Q38"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,tested_people_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q38") %>%
mutate(group=paste(dataset, wikidata_id,tested_people_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( tested_people_log_y_hat_percent_change = breakpoints(formula=tested_people_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p4a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 tested_people")
p4b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("Italy Q38 tested_people")+ ylab("Daily Percent Change tested_people")
#p4a / p4b
#South Korea
#"Q884"
test <- lhs_long_clean_imputed %>% mutate(group=paste(dataset,wikidata_id,tested_people_log_y_hat_percent_change)) %>% filter(wikidata_id=="Q884") %>%
mutate(group=paste(dataset, wikidata_id,tested_people_log_group_number)) %>%
arrange(date_asdate) #%>%
#mutate( tested_people_log_y_hat_percent_change = breakpoints(formula=tested_people_log_y_hat_percent_change ~ 1, data=. ) %>% fitted.values() )
p5a <- test %>%
ggplot() +
geom_point( aes(x=date_asdate, y=tested_people_log, color=dataset), alpha=.3) +
geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 tested_people")
p5b <- test %>%
ggplot() +
geom_point( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change, color=dataset), alpha=.3) +
geom_line(aes(x=date_asdate , y=tested_people_log_y_hat_percent_change_y_hat ), alpha=1, color="black") +
#geom_smooth( aes(x=date_asdate , y=tested_people_log_y_hat_percent_change), alpha=.3, span=.05) + #, span=.05
#geom_line( aes(x=date_asdate, y=tested_people_log_y_hat, color=dataset, group=group)) + #
#geom_line(data=temp_df2, aes(x=date_asdate, y=y_hat_mean), color="black", linetype = "dashed") +
theme_bw() +
ggtitle("South Korea Q884 tested_people") + ylab("Daily Percent Change tested_people")
#p5a / p5b
Note that China counts of testing are almost never given at the national level. We have some broken down by specific provinces but tables usually don’t have a “China” row.
(p0a + p1a + p2a ) / (p0b + p1b + p2b )

(p3a + p4a + p5a) / (p3b + p4b + p5b)

LS0tCnRpdGxlOiAiVGhlIE1hY2hpbmUgTGVhcm5pbmcgZm9yIFNvY2lhbCBTY2llbmNlIEdsb2JhbCBTdWJuYXRpb25hbCBDb3ZpZCBDb3VudHMgRGF0c2V0IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogaGlkZQpkYXRlOiAKYXV0aG9yOiAKYWZmaWxpYXRpb246IERpcmVjdG9yLCBNYWNoaW5lIExlYXJuaW5nIGZvciBTb2NpYWwgU2NpZW5jZSBMYWIsIENlbnRlciBmb3IgUGVhY2UgYW5kIFNlY3VyaXR5IFN0dWRpZXMsIFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSBTYW4gRGllZ28KZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpSZXggVy4gRG91Z2xhc3MKCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJsb2NrcXVvdGUgewogICAgcGFkZGluZzogMTBweCAyMHB4OwogICAgbWFyZ2luOiAwIDAgMjBweDsKICAgIGZvbnQtc2l6ZTogMTRweDsKICAgIGJvcmRlci1sZWZ0OiA1cHggc29saWQgI2VlZTsKfQo8L3N0eWxlPgoKIyBJbnRyb2R1Y3Rpb24KCiMjIExpYnJhcnkgTG9hZHMKCmBgYHtyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CiNsaWJyYXJpZXMKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkodGlkeXZlcnNlKQoKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigicm9wZW5zY2kvVVNBYm91bmRhcmllcyIpCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInJvcGVuc2NpL1VTQWJvdW5kYXJpZXNEYXRhIikKbGlicmFyeShVU0Fib3VuZGFyaWVzKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCdVU0Fib3VuZGFyaWVzJykKZGF0YShzdGF0ZV9jb2RlcykKCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShnZ2hpZ2hsaWdodCkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoUjApICAjIGNvbnNpZGVyIG1vdmluZyBhbGwgbGlicmFyeSBjb21tYW5kcyB0byB0b3AgLS0gdGhpcyBvbmUgd2FzIGluIGEgbG9vcCBiZWxvdwoKbGlicmFyeShXaWtpZGF0YVIpCmxpYnJhcnkoY291bnRyeWNvZGUpCgpsaWJyYXJ5KHVzbWFwKSA7ICMgaW5zdGFsbC5wYWNrYWdlcygndXNtYXAnKQpkYXRhKHN0YXRlcG9wKQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJyb3BlbnNjaS9VU0Fib3VuZGFyaWVzIikKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigicm9wZW5zY2kvVVNBYm91bmRhcmllc0RhdGEiKQpsaWJyYXJ5KFVTQWJvdW5kYXJpZXMpIDsgI2luc3RhbGwucGFja2FnZXMoJ1VTQWJvdW5kYXJpZXMnKQpkYXRhKHN0YXRlX2NvZGVzKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCgpsaWJyYXJ5KGpzb25saXRlKQoKI1RoaXMgaXMgdG9vIHNsb3cgaXQncyBkb3dubG9hZGluZyBlYWNoCmxpYnJhcnkoR0FETVRvb2xzKQpsaWJyYXJ5KHN0cnVjY2hhbmdlKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCdzdHJ1Y2NoYW5nZScpCmxpYnJhcnkodHNpYmJsZSkKCmxpYnJhcnkocGF0Y2h3b3JrKQoKYGBgCiMjIERhdGEgTG9hZGluZyBhbmQgQ2xlYW5pbmcKCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OCx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQoKbGlicmFyeSh0c2liYmxlKQoKbGhzX2xvbmcgPC0gcmVhZFJEUygiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTY292aWQxOS9kYXRhX3RlbXAvbGhzX2xvbmcuUmRzIikKI2RpbShsaHNfbG9uZykgIzE4NywzMDUKCmxoc19sb25nX2NsZWFuIDwtIGxoc19sb25nICU+JSAKICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChkYXRhc2V0LCBnaWQsZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCAsZGF0ZV9hc2RhdGUsIGNvbmZpcm1lZCwgZGVhdGhzLCB0ZXN0ZWRfcGVvcGxlLCB0ZXN0ZWRfc2FtcGxlcykgJT4lCiAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGRhdGFzZXQsIGdpZCxnZW9uYW1laWQsIHdpa2lkYXRhX2lkICxkYXRlX2FzZGF0ZSkgJT4lICNpZiB0aGUgc2FtZSBzb3VyY2UgaGFzIG11bHRpcGxlIHZhbHVlcyBvbiB0aGUgc2FtZSB0aGluZyBvbiB0aGUgc2FtZSBkYXksIG9yIGRpZmZlcmVudCB2YWx1ZXMgYWNyb3NzIHVubWVyZ2VkIG9icywgdGhlbiB0YWtlIHRoZSBtYXgKICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlX2FsbChtYXgsIG5hLnJtPVQpICU+JSAKICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICBtdXRhdGVfaWYoaXMubnVtZXJpYywgbGlzdCh+bmFfaWYoLiwgLUluZikpKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGxpc3Qofm5hX2lmKC4sIEluZikpKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRhdGFzZXRfZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZD0gcGFzdGUoZGF0YXNldCxnaWQsZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgc2VwPSJfIikgICkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShnaWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkPSBwYXN0ZShnaWQsZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgc2VwPSJfIikgICkgJT4lCiAgCiAgICAgICAgICAgICAgICAgIGZpbHRlcighaXMubmEoZGF0ZV9hc2RhdGUpKSAlPiUKICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICNGaXJzdCBkcm9wIGFueXRoaW5nIHRoYXQncyBuZWdhdGl2ZS4gU2hvdWxkbid0IGJlIGFueSBuZWdhdGl2ZXMuCiAgICAgICAgICAgICAgICAgIGZpbHRlcihpcy5uYShjb25maXJtZWQpIHwgY29uZmlybWVkPj0wKSAlPiUKICAgICAgICAgICAgICAgICAgZmlsdGVyKGlzLm5hKGRlYXRocykgfCBkZWF0aHM+PTApICU+JQogICAgICAgICAgICAgICAgICBmaWx0ZXIoaXMubmEodGVzdGVkX3Blb3BsZSkgfCB0ZXN0ZWRfcGVvcGxlPj0wKSAlPiUKICAgICAgICAgICAgICAgICAgZmlsdGVyKGlzLm5hKHRlc3RlZF9zYW1wbGVzKSB8IHRlc3RlZF9zYW1wbGVzPj0wKSAlPiUKICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICNUaGVuIHNldCAwcyB0byBOQSwgd2UgZG9uJ3QgdHJ1c3QgTkFzCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWQ9aWZlbHNlKGNvbmZpcm1lZD09MCwgTkEsIGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzPWlmZWxzZShkZWF0aHM9PTAsIE5BLCBkZWF0aHMpKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGU9aWZlbHNlKHRlc3RlZF9wZW9wbGU9PTAsIE5BLCB0ZXN0ZWRfcGVvcGxlKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZSh0ZXN0ZWRfc2FtcGxlcz1pZmVsc2UodGVzdGVkX3NhbXBsZXM9PTAsIE5BLCB0ZXN0ZWRfc2FtcGxlcykpICU+JQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICNUaGVuIGNoZWNrIGZpcnN0IGRpZmZlcmVuY2VzIGFuZCBkcm9wIGFueXRoaW5nIHRoYXQgZG9lc24ndCB3ZWFrbHkgaW5jcmVhc2UgbW9ub3RvbmljYWxseQogICAgICAgICAgICAgICAgICBncm91cF9ieShkYXRhc2V0LCBnaWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9jdW1tYXg9Y29uZmlybWVkICU+JSByZXBsYWNlX25hKDApICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdW1tYXgoKSwgZGVhdGhzX2N1bW1heD1kZWF0aHMlPiUgcmVwbGFjZV9uYSgwKSAlPiUgY3VtbWF4KCksIHRlc3RlZF9wZW9wbGVfY3VtbWF4PXRlc3RlZF9wZW9wbGUlPiUgcmVwbGFjZV9uYSgwKSAlPiUgY3VtbWF4KCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RlZF9zYW1wbGVzX2N1bW1heD10ZXN0ZWRfc2FtcGxlcyU+JSByZXBsYWNlX25hKDApICU+JSBjdW1tYXgoKSkgJT4lCiAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUgIAogIAogICAgICAgICAgICAgICAgICAjQWJvdXQgNGsgb2YgdGhlc2Ugb2JzZXJ2YXRpb25zIHNob3cgYSBkZWNyZWFzZSBmcm9tIG9uZSB0aW1lIHN0ZXAgdG8gdGhlIG5leHQgd2hpY2ggc3VnZ2VzdHMgZWl0aGVyIGFuIG9yaWdpbmFsIGVycm9yIG9yIGEgam9pbmluZyBlcnJvcgogICAgICAgICAgICAgICAgICAjV2UncmUgZ29pbmcgdG8gc3RyYWlnaHQgZHJvcCB0aG9zZSBvYnNlcnZhdGlvbnMgYXMgYSBjbGVhbmluZyBzdGVwCiAgICAgICAgICAgICAgICAgICN0aGlzIGlzbid0IGVub3VnaCBiZWNhdXNlIGlmIHlvdSBoYXZlIGNvbnNlY3V0aXZlIG1pc3Rha2VzIGl0J2xsIHNob3cgYSBwb3NpdGl2ZSBmZCBldmVuIGlmIGl0J3Mgbm90IGdvb2QgZW5vdWdoCiAgICAgICAgICAgICAgICAgIGZpbHRlciggKGlzLm5hKGNvbmZpcm1lZCkgfCBjb25maXJtZWQ+PWNvbmZpcm1lZF9jdW1tYXgpICYgICNuZXZlciBhbGxvdyBmb3IgYSByZXZlcnNhbAogICAgICAgICAgICAgICAgICAgICAgICAgIChpcy5uYShkZWF0aHMpIHwgZGVhdGhzPj1kZWF0aHNfY3VtbWF4KSAmICAgICAgICAjbmV2ZXIgYWxsb3cgZm9yIGEgcmV2ZXJzYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAoaXMubmEodGVzdGVkX3Blb3BsZSkgfCB0ZXN0ZWRfcGVvcGxlPj10ZXN0ZWRfcGVvcGxlX2N1bW1heCkgJiAgI25ldmVyIGFsbG93IGZvciBhIHJldmVyc2FsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKGlzLm5hKHRlc3RlZF9zYW1wbGVzKSB8IHRlc3RlZF9zYW1wbGVzPj10ZXN0ZWRfc2FtcGxlc19jdW1tYXgpICAjbmV2ZXIgYWxsb3cgZm9yIGEgcmV2ZXJzYWwKICAgICAgICAgICAgICAgICAgICAgICAgICApICU+JQogICN3ZSdyZSBnb2luZyB0byBnbyBvbmUgc3RlcCBmdXJ0aGVyIGFuZCByZXF1aXJlIGVpdGhlciBjb25maXJtZWQgb3IgdGVzdGVkIHRvIGJlIHN0cmljdGx5IGhpZ2hlcgogICNJbiB3b3JkcywgZHVyaW5nIGFuIGVwaXNvZGUgd2UgZG9uJ3QgYmVsaWV2ZSByZXBvcnRzIG1lYW4gIm5vIG5ldyBjYXNlcyIganVzdCBubyBuZXcgZ29vZCByZXBvcnRpbmcKICAjbWV0YWJpb3RhIGlzIHRoZSB3b3JzdCBvZmZlbmRlciBoZXJlIHNvIHJlc3RyaWN0aW5nIGl0IHRvIGp1c3QgdGhhdAogIGZpbHRlciggISgKICAgICAgICAgICAgZGF0YXNldD09Im1ldGFiaW90YSIgJiAjaXMgbWV0YWJpb3RhCiAgICAgICAgICAgICghaXMubmEoY29uZmlybWVkKSAmICAgI3dpdGggYSBub24gbWlzc2luZyBjb25maXJtZWQKICAgICAgICAgICAgICBjb25maXJtZWQ8PWNvbmZpcm1lZF9jdW1tYXggKSAjdGhhdCBpcyBlcXVhbCB0byBvciBsZXNzIHRoYW4gdGhlIGN1bXVsYXRpdmUgbWF4IHVudGlsIHRoZW4uCiAgICAgICAgICAgICkgI3JlamVjdCB0aGVzZQogICAgICAgICAgKSAlPiUgI21ldGFiaW90YSBpcyByZWFsbHkgcHJvYmxlbWF0aWMgOTAlIG9mIHdoYXQgd2UncmUgZG9pbmcgaXMgdHJ5aW5nIHRvIGFjY291bnQgZm9yIGl0CiAgCiAgI0Fsc28gcmVqZWN0IGFueSB3aGVyZSBkZWF0aHMgYXJlIGdyZWF0ZXIgdGhhbiBjb25maXJtZWQKICBmaWx0ZXIoaXMubmEoY29uZmlybWVkKSB8IGlzLm5hKGRlYXRocykgfCBjb25maXJtZWQ+PWRlYXRocykgJT4lCiAgCiAgI2Fsc28gcmVqZWN0IGFueSB3aGVyZSBjb25maXJtZWQgZG9lc24ndCB2YXJ5IAogIGdyb3VwX2J5KGdpZCAsICBnZW9uYW1laWQgLHdpa2lkYXRhX2lkKSAlPiUgI2Nob3NlIG5vdCB0byBkbyBieSBkYXRhc2V0IGJlY2F1c2UgdGVzdGluZyBkYXRhc2V0cyBtaWdodCBub3QgaGF2ZSBjb25maXJtZWQKICAgIGZpbHRlcih2YXIoY29uZmlybWVkLCBuYS5ybT1UKT4wKSAlPiUKICB1bmdyb3VwKCkKCiAgCiNkaW0obGhzX2xvbmdfY2xlYW4pICMyODEsNDY0ICMyOTIsNTgwICMyOTkyMTMgIzE4MSw1NjMKCnNhdmVSRFMobGhzX2xvbmdfY2xlYW4sCiAgICAgICAgIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2xoc19sb25nX2NsZWFuZC5SZHMiKQoKYGBgCgpTdW1tYXJ5IFN0YXRpc3RpY3Mgb2YgT3VyIERhdGEKCmBgYHtyfQpwcmludCgiTnVtYmVyIG9mIG9ic2VydmF0aW9ucyIpCmRpbShsaHNfbG9uZ19jbGVhbikKCnByaW50KCJOdW1iZXIgb2YgbG9jYXRpb25zIikKbGhzX2xvbmdfY2xlYW4kd2lraWRhdGFfaWQgJT4lIHVuaXF1ZSgpICU+JSBsZW5ndGgoKSAjMywzNzMKCnByaW50KCJOdW1iZXIgb2YgRGF5cyIpCmxoc19sb25nX2NsZWFuJGRhdGVfYXNkYXRlICU+JSB1bmlxdWUoKSAlPiUgbGVuZ3RoKCkgIzExMwoKbGlicmFyeShEVCkgI2h0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vRFQvCmxoc19sb25nX2NsZWFuICU+JSBjb3VudChkYXRhc2V0KSAlPiUgYXJyYW5nZSgtbikgJT4lIERUOjpkYXRhdGFibGUob3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDIwLCBhdXRvV2lkdGggPSBUUlVFKSkKCiNsaWJyYXJ5KGd0KQojbGhzX2xvbmdfY2xlYW4gJT4lIGNvdW50KGRhdGFzZXQpICU+JSBhcnJhbmdlKC1uKSAlPiUgZ3QoKSAlPiUgCiMgdGFiX2hlYWRlcigKIyAgICB0aXRsZSA9IG1kKCJMb2NhdGlvbi1EYXlzIGJ5IERhdGFzZXQiKSMsCiMgICAgI3N1YnRpdGxlID0gIk51bWJlciBvZiBEYXlzIHdpdGggRGF0YSBieSBEYXRhc2V0IgojICApICU+JQojICBmbXRfbWlzc2luZyggY29sdW1ucz1ldmVyeXRoaW5nKCksIHJvd3M9TlVMTCxtaXNzaW5nX3RleHQgPSAwKQoKYGBgCgoKIyBTcGF0aWFsIFZhcmlhdGlvbiBpbiBEYXRhIEF2YWlsYWJpbGl0eQoKIyMgQ291bnRyeSBMZXZlbCBEYXRhIEF2YWlsYWJpbGl0eQoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQoKI2dhZG0zNiA9IHN0X3JlYWQoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2dhZG0vZGF0YV9pbi9nYWRtMzZfZ3BrZy9nYWRtMzYuZ3BrZyIpCiNzdF9sYXllcnMoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2dhZG0zNl9ieWNvdW50cnkvZ2FkbTM2X2xldmVsc19ncGtnL2dhZG0zNl9sZXZlbHMuZ3BrZyIpCmdhZG0zNl9sZXZlbHNfMCA9IHN0X3JlYWQoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2dhZG0zNl9ieWNvdW50cnkvZ2FkbTM2X2xldmVsc19ncGtnL2dhZG0zNl9sZXZlbHMuZ3BrZyIsIGxheWVyPSJsZXZlbDAiKSAgJT4lCiAgICAgICAgICAgICAgICAgIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBGQUxTRSwgZFRvbGVyYW5jZSA9MC4xKSAjICAwLjAyNSB0aGlzIGlzIHN1cHBvc2VkbHkgYnJva2VuIHVwIGJ5IDYgbGV2ZWxzIGFuZCBzbyBzaG91bGQgaGF2ZSB1LnMuIAoKI3Bsb3QoZ2FkbTM2X2xldmVsc18wKQojZGltKGdhZG0zNl9sZXZlbHNfMF9zZiRzZikKI2dhZG1fcGxvdChnYWRtMzZfbGV2ZWxzXzBfc2YpCmxoc19sb25nX3BsYWNlX3NvdXJjZXMgPC0gbGhzX2xvbmcgICU+JSBkcGx5cjo6c2VsZWN0KGdpZCwgICBnZW9uYW1laWQsIHdpa2lkYXRhX2lkLCBkYXRhc2V0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGdpZCwgIGdlb25hbWVpZCwgd2lraWRhdGFfaWQpICU+JSBjb3VudChkYXRhc2V0KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoZ2lkLCAgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShkYXRhc2V0c19uPW4oKSkgCgpwMCA8LSBnYWRtMzZfbGV2ZWxzXzAgJT4lIAogICAgICBsZWZ0X2pvaW4obGhzX2xvbmdfcGxhY2Vfc291cmNlcyAlPiUgZHBseXI6OnNlbGVjdChnaWQ9Z2lkLCBkYXRhc2V0c19uKSAlPiUgIGxlZnRfam9pbiggZ2FkbTM2X2xldmVsc18wICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGRwbHlyOjpzZWxlY3QoZ2lkPUdJRF8wLCBOQU1FXzApICAlPiUgZGlzdGluY3QoKSAgKQogICAgICAgICAgICAgICAgKSAlPiUKICAgICAgI3JlcGxhY2VfbmEobGlzdChkYXRhc2V0c19uID0gMCkpICU+JSAKICAgICAgZ2dwbG90KCkgKyBnZW9tX3NmKGFlcyhmaWxsID0gZGF0YXNldHNfbikpICsKICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3c9InJlZCIsIGhpZ2g9ImdyZWVuIikgKwogICAgICB0aGVtZV9idygpIApgYGAKCgoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02LHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KcDAgKyBnZ3RpdGxlKCJDb3ZpZCBDb3VudCBEYXRhIEF2YWlsYWJpbGl0eSBhdCB0aGUgQ291bnRyeSBMZXZlbCIpCmBgYAoKYGBge3J9CnRlbXAgPC0gZ2FkbTM2X2xldmVsc18wICU+JQogICBsZWZ0X2pvaW4oCiAgIGxoc19sb25nICAlPiUgY291bnQoZ2lkLCBkYXRhc2V0KSAlPiUgcmVuYW1lKEdJRF8wPWdpZCkgI3RoZXJlIGFyZSBzdGlsbCBkdXBlIGdlb25hbWVzIHdpa2lkYXRhIHRvIGdpZCBtYXRjaGVzIHRoYXQgbmVlZCB0byBiZSBmaXhlZCBnZW9uYW1laWQsIHdpa2lkYXRhX2lkLCAKKSAKCnRlbXBfd2lkZSA8LSB0ZW1wICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGRwbHlyOjpzZWxlY3QoQ291bnRyeT1OQU1FXzAsIGRhdGFzZXQsIG4pICU+JSBkaXN0aW5jdCgpICU+JSBwaXZvdF93aWRlciggaWRfY29scyA9IENvdW50cnksIG5hbWVzX2Zyb20gPSBkYXRhc2V0LAogIHZhbHVlc19mcm9tID0gbiwgdmFsdWVzX2ZpbGwgPSBOVUxMLCB2YWx1ZXNfZm4gPSBOVUxMKSAKCnRlbXBfd2lkZSAlPiUgRFQ6OmRhdGF0YWJsZShvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMjAsIGF1dG9XaWR0aCA9IFRSVUUpKQoKI2luc3RhbGwucGFja2FnZXMoJ2d0JykKI2xpYnJhcnkoZ3QpCiN0ZW1wX3dpZGUgJT4lIGd0KCkgJT4lIAojIHRhYl9oZWFkZXIoCiMgICAgdGl0bGUgPSBtZCgiRGF0YSBBdmFpbGFiaWxpdHkgYnkgQ291bnRyeSIpLAojICAgIHN1YnRpdGxlID0gIk51bWJlciBvZiBEYXlzIHdpdGggRGF0YSBieSBEYXRhc2V0IgojICApICU+JQojICBmbXRfbWlzc2luZyggY29sdW1ucz1ldmVyeXRoaW5nKCksIHJvd3M9TlVMTCxtaXNzaW5nX3RleHQgPSAwKQoKYGBgCgojIyBTdGF0ZS9Qcm92aW5jZSBMZXZlbCBEYXRhIEF2YWlsYWJpbGl0eQoKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KZ2FkbTM2X2xldmVsc18xID0gc3RfcmVhZCgiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTY292aWQxOS9kYXRhX3RlbXAvZ2FkbTM2X2J5Y291bnRyeS9nYWRtMzZfbGV2ZWxzX2dwa2cvZ2FkbTM2X2xldmVscy5ncGtnIiwgbGF5ZXI9ImxldmVsMSIpICAlPiUKICBzdF9zaW1wbGlmeShwcmVzZXJ2ZVRvcG9sb2d5ID0gRkFMU0UsIGRUb2xlcmFuY2UgPTAuMSkgIyAgMC4wMjUgdGhpcyBpcyBzdXBwb3NlZGx5IGJyb2tlbiB1cCBieSA2IGxldmVscyBhbmQgc28gc2hvdWxkIGhhdmUgdS5zLiAKCgpwMSA8LSBnYWRtMzZfbGV2ZWxzXzEgJT4lIAogIGxlZnRfam9pbihsaHNfbG9uZ19wbGFjZV9zb3VyY2VzICU+JSBkcGx5cjo6c2VsZWN0KGdpZD1naWQsIGRhdGFzZXRzX24pICU+JSAgbGVmdF9qb2luKCBnYWRtMzZfbGV2ZWxzXzEgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgZHBseXI6OnNlbGVjdChnaWQ9R0lEXzEsIE5BTUVfMSkgJT4lIGRpc3RpbmN0KCkgICkKICApICU+JQogICNyZXBsYWNlX25hKGxpc3QoZGF0YXNldHNfbiA9IDApKSAlPiUgCiAgZ2dwbG90KCkgKyBnZW9tX3NmKGFlcyhmaWxsID0gZGF0YXNldHNfbikpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdz0icmVkIiwgaGlnaD0iZ3JlZW4iKSArCiAgdGhlbWVfYncoKSAKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTYsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQpwMQpgYGAKCmBgYHtyfQp0ZW1wIDwtIGdhZG0zNl9sZXZlbHNfMSAlPiUKICAgbGVmdF9qb2luKAogICBsaHNfbG9uZyAgJT4lIGNvdW50KGdpZCwgZGF0YXNldCkgJT4lIHJlbmFtZShHSURfMT1naWQpICN0aGVyZSBhcmUgc3RpbGwgZHVwZSBnZW9uYW1lcyB3aWtpZGF0YSB0byBnaWQgbWF0Y2hlcyB0aGF0IG5lZWQgdG8gYmUgZml4ZWQgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgCikgCgp0ZW1wX3dpZGUgPC0gdGVtcCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBkcGx5cjo6c2VsZWN0KENvdW50cnk9TkFNRV8wLCBBZG1pbjE9TkFNRV8xLCBkYXRhc2V0LCBuKSAlPiUgZGlzdGluY3QoKSAlPiUgcGl2b3Rfd2lkZXIoIGlkX2NvbHMgPSBDb3VudHJ5OkFkbWluMSwgbmFtZXNfZnJvbSA9IGRhdGFzZXQsCiAgdmFsdWVzX2Zyb20gPSBuLCB2YWx1ZXNfZmlsbCA9IE5VTEwsIHZhbHVlc19mbiA9IE5VTEwpICU+JSBtdXRhdGUodG90YWwgPSByb3dTdW1zKC5bLWMoMSwyKV0sIG5hLnJtID0gVCkpCgp0ZW1wX3dpZGUgJT4lIGZpbHRlcih0b3RhbD4wKSAlPiUgRFQ6OmRhdGF0YWJsZShvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsIGF1dG9XaWR0aCA9IFRSVUUpKQoKYGBgCgojIyBDb3VudHkgRGlzdHJpY3QgTGV2ZWwgRGF0YSBBdmFpbGFiaWxpdHkKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KZ2FkbTM2X2xldmVsc18yID0gc3RfcmVhZCgiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTY292aWQxOS9kYXRhX3RlbXAvZ2FkbTM2X2J5Y291bnRyeS9nYWRtMzZfbGV2ZWxzX2dwa2cvZ2FkbTM2X2xldmVscy5ncGtnIiwgbGF5ZXI9ImxldmVsMiIpICAlPiUKICBzdF9zaW1wbGlmeShwcmVzZXJ2ZVRvcG9sb2d5ID0gRkFMU0UsIGRUb2xlcmFuY2UgPSAwLjAwMSkgIyAgMC4wMjUgdGhpcyBpcyBzdXBwb3NlZGx5IGJyb2tlbiB1cCBieSA2IGxldmVscyBhbmQgc28gc2hvdWxkIGhhdmUgdS5zLiBJIGhhdmUgdG8ga2VlcCBzaHJpbmtpbmcgaXQgc28gbWlzaXNuZyBnb2VzIHRvIHplcm8gCgpwMiA8LSBnYWRtMzZfbGV2ZWxzXzIgJT4lIAogIGxlZnRfam9pbihsaHNfbG9uZ19wbGFjZV9zb3VyY2VzICU+JSBkcGx5cjo6c2VsZWN0KGdpZD1naWQsIGRhdGFzZXRzX24pICU+JSAgbGVmdF9qb2luKCBnYWRtMzZfbGV2ZWxzXzIgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgZHBseXI6OnNlbGVjdChnaWQ9R0lEXzIsIE5BTUVfMikgJT4lIGRpc3RpbmN0KCkgICkKICApICU+JQogICNyZXBsYWNlX25hKGxpc3QoZGF0YXNldHNfbiA9IDApKSAlPiUgCiAgZ2dwbG90KCkgKyBnZW9tX3NmKGFlcyhmaWxsID0gZGF0YXNldHNfbiksbHdkID0gMCkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93PSJibHVlIiwgaGlnaD0icmVkIikgKwogIHRoZW1lX2J3KCkgCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02LHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KCnAyCgpgYGAKCgpgYGB7cn0KdGVtcCA8LSBnYWRtMzZfbGV2ZWxzXzIgJT4lCiAgIGxlZnRfam9pbigKICAgbGhzX2xvbmcgICU+JSBjb3VudChnaWQsIGRhdGFzZXQpICU+JSByZW5hbWUoR0lEXzI9Z2lkKSAjdGhlcmUgYXJlIHN0aWxsIGR1cGUgZ2VvbmFtZXMgd2lraWRhdGEgdG8gZ2lkIG1hdGNoZXMgdGhhdCBuZWVkIHRvIGJlIGZpeGVkIGdlb25hbWVpZCwgd2lraWRhdGFfaWQsIAopIAoKdGVtcF93aWRlIDwtIHRlbXAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgZHBseXI6OnNlbGVjdChDb3VudHJ5PU5BTUVfMCwgQWRtaW4xPU5BTUVfMSwgQWRtaW4yPU5BTUVfMiwgZGF0YXNldCwgbikgJT4lIGRpc3RpbmN0KCkgJT4lIHBpdm90X3dpZGVyKCBpZF9jb2xzID0gQ291bnRyeTpBZG1pbjIsIG5hbWVzX2Zyb20gPSBkYXRhc2V0LAogIHZhbHVlc19mcm9tID0gbiwgdmFsdWVzX2ZpbGwgPSBOVUxMLCB2YWx1ZXNfZm4gPSBOVUxMKSAlPiUgbXV0YXRlKHRvdGFsID0gcm93U3VtcyguWy1jKDEsMiwzKV0sIG5hLnJtID0gVCkpCgp0ZW1wX3dpZGUgJT4lIGZpbHRlcih0b3RhbD4wKSAlPiUgRFQ6OmRhdGF0YWJsZShvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsIGF1dG9XaWR0aCA9IFRSVUUpKQoKYGBgCgojIyBDb3VudHJ5IERhdGEgQXZhaWxhYmlsaXR5IG9mIFRlc3RpbmcKCmBgYHtyfQoKbGhzX2xvbmdfcGxhY2Vfc291cmNlc190ZXN0aW5nIDwtIGxoc19sb25nICAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QoZ2lkLCAgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgZGF0ZV9hc2RhdGUsIGNvbmZpcm1lZCwgdGVzdGVkX3Blb3BsZSwgdGVzdGVkX3NhbXBsZXMpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoZ2lkLCAgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZV9pZihpcy5udW1lcmljLCBtYXgsIG5hLnJtPVQpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCFkdXBsaWNhdGVkKGRhdGVfYXNkYXRlKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmdyb3VwKCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGVfaWYoaXMubnVtZXJpYywgbGlzdCh+bmFfaWYoLiwgLUluZikpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZV9pZihpcy5udW1lcmljLCBsaXN0KH5uYV9pZiguLCBJbmYpKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUocGVyY2VudF9vZl9kYXlzX3dpdGhvdXRfdGVzdGluZz0haXMubmEoZGF0ZV9hc2RhdGUpICYgKGlzLm5hKHRlc3RlZF9wZW9wbGUpICYgaXMubmEodGVzdGVkX3NhbXBsZXMpICApKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoZ2lkLCAgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnRfb2ZfZGF5c193aXRob3V0X3Rlc3Rpbmc9c3VtKHBlcmNlbnRfb2ZfZGF5c193aXRob3V0X3Rlc3RpbmcsIG5hLnJtPVQpL24oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUocGVyY2VudF9vZl9kYXlzX3dpdGhfdGVzdGluZz0gMS1wZXJjZW50X29mX2RheXNfd2l0aG91dF90ZXN0aW5nKSAKCgpwMF90ZXN0aW5nIDwtIGdhZG0zNl9sZXZlbHNfMCAlPiUgCiAgICAgIGxlZnRfam9pbihsaHNfbG9uZ19wbGFjZV9zb3VyY2VzX3Rlc3RpbmcgJT4lIGRwbHlyOjpzZWxlY3QoZ2lkPWdpZCwgcGVyY2VudF9vZl9kYXlzX3dpdGhfdGVzdGluZykgJT4lICBsZWZ0X2pvaW4oIGdhZG0zNl9sZXZlbHNfMCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBkcGx5cjo6c2VsZWN0KGdpZD1HSURfMCwgTkFNRV8wKSAgJT4lIGRpc3RpbmN0KCkgICkKICAgICAgICAgICAgICAgICkgJT4lCiAgICAgICNyZXBsYWNlX25hKGxpc3QoZGF0YXNldHNfbiA9IDApKSAlPiUgCiAgICAgIGdncGxvdCgpICsgZ2VvbV9zZihhZXMoZmlsbCA9IHBlcmNlbnRfb2ZfZGF5c193aXRoX3Rlc3RpbmcpKSArCiAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93PSJyZWQiLCBoaWdoPSJncmVlbiIpICsKICAgICAgdGhlbWVfYncoKSArIGdndGl0bGUoIlBlcmNlbnQgb2YgRGF5cyB3aXRoIFRlc3RpbmcgY291bnRzIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTYsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQpwMF90ZXN0aW5nCmBgYApgYGB7cix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpwMV90ZXN0aW5nIDwtIGdhZG0zNl9sZXZlbHNfMSAlPiUgCiAgbGVmdF9qb2luKGxoc19sb25nX3BsYWNlX3NvdXJjZXNfdGVzdGluZyAlPiUgZHBseXI6OnNlbGVjdChnaWQ9Z2lkLCBwZXJjZW50X29mX2RheXNfd2l0aF90ZXN0aW5nKSAlPiUgIGxlZnRfam9pbiggZ2FkbTM2X2xldmVsc18xICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGRwbHlyOjpzZWxlY3QoZ2lkPUdJRF8xLCBOQU1FXzEpICU+JSBkaXN0aW5jdCgpICApCiAgKSAlPiUKICAjcmVwbGFjZV9uYShsaXN0KGRhdGFzZXRzX24gPSAwKSkgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9zZihhZXMoZmlsbCA9IHBlcmNlbnRfb2ZfZGF5c193aXRoX3Rlc3RpbmcpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3c9InJlZCIsIGhpZ2g9ImdyZWVuIikgKwogIHRoZW1lX2J3KCkgICsgZ2d0aXRsZSgiUGVyY2VudCBvZiBEYXlzIHdpdGggVGVzdGluZyBjb3VudHMiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CnAxX3Rlc3RpbmcKYGBgCgojIERhdGEgQXZhaWxhYmlsaXR5IGFuZCBJbnRlcnBvbGF0aW9uIG92ZXIgVGltZQoKYGBge3Isd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KCiN0ZXN0IDwtIGxoc19sb25nICU+JSBncm91cF9ieShkYXRhc2V0LCBnaWQsIGdlb25hbWVpZCwgd2lraWRhdGFfaWQsIGRhdGVfYXNkYXRlKSAlPiUgc3VtbWFyaXplKG49bigpKQoKYWxsX25hIDwtIGZ1bmN0aW9uKHgpIGFueSghaXMubmEoeCkpICNodHRwczovL2ludGVsbGlwYWF0LmNvbS9jb21tdW5pdHkvMTI5OTkvcmVtb3ZlLWNvbHVtbnMtZnJvbS1kYXRhZnJhbWUtd2hlcmUtYWxsLXZhbHVlcy1hcmUtbmEKCiNiaW5nIGxvb2tzIG9mZiBieSBhIGRheSBmcm9tIHRoZSBvdGhlciBvbmVzCmxoc193aWRlX3Fjb2RlIDwtIGxoc19sb25nICU+JSAKICAgICAgICAgICAgICAgICAgZmlsdGVyKCFpcy5uYSh3aWtpZGF0YV9pZCkgJiAhaXMubmEoZGF0ZV9hc2RhdGUpKSAlPiUKICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoZ2lkLCBnZW9uYW1laWQsIHdpa2lkYXRhX2lkLCBkYXRlX2FzZGF0ZSkgJT4lICBtdXRhdGUoY29uZmlybWVkX3Zhcj12YXIoY29uZmlybWVkLCBuYS5ybT1UKSwgZGVhdGhzX3Zhcj12YXIoZGVhdGhzLCBuYS5ybT1UKSkgJT4lIHVuZ3JvdXAoKSAlPiUKICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChkYXRhc2V0LCBnaWQsIGdlb25hbWVpZCwgd2lraWRhdGFfaWQsIGRhdGVfYXNkYXRlLGNvbmZpcm1lZCwgZGVhdGhzLCB0ZXN0ZWRfc2FtcGxlcywgdGVzdGVkX3Blb3BsZSkgJT4lCiAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGRhdGFzZXQsIGdpZCwgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgZGF0ZV9hc2RhdGUpICU+JSAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsbWF4LG5hLnJtPVQpICU+JSB1bmdyb3VwKCkgJT4lICN0aGlzIGlzIGEgaGFjaywgd2Ugc2hvdWxkIGhhdmUgZHVwZXMgd2l0aGluIGRhdGFzZXRzCiAgICAgICAgICAgICAgICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBkYXRhc2V0LCB2YWx1ZXNfZnJvbSA9IGMoY29uZmlybWVkLCBkZWF0aHMsIHRlc3RlZF9zYW1wbGVzLCB0ZXN0ZWRfcGVvcGxlKSApICU+JSAKICAgICAgICAgICAgICAgICAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGxpc3Qofm5hX2lmKGFicyguKSwgSW5mKSkpICU+JSAjaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTIxODg1MDkvY2xlYW5pbmctaW5mLXZhbHVlcy1mcm9tLWFuLXItZGF0YWZyYW1lCiAgICAgICAgICAgICAgICAgIHNlbGVjdF9pZihhbGxfbmEpIAoKZGltKGxoc193aWRlX3Fjb2RlKSAjODIsMTU3IDgyayBwbGFjZS9kYXkgb2JzZXJ2YXRpb25zCgpsZW5ndGgodW5pcXVlKGxoc193aWRlX3Fjb2RlJHdpa2lkYXRhX2lkKSkgIzM2OTcgI2FsbW9zdCA0ayAKCnRlc3QgPC0gbGhzX3dpZGVfcWNvZGUgJT4lIGRwbHlyOjpzZWxlY3Qoc3RhcnRzX3dpdGgoImNvbmZpcm1lZCIpKSAlPiUgZGlzdGluY3QoKSAKI2Nvcih0ZXN0LCB1c2U9InBhaXJ3aXNlLmNvbXBsZXRlLm9icyIpCgpsaHNfbG9uZ19tZWRpYW4gPC0gbGhzX2xvbmcgJT4lIGdyb3VwX2J5KGdpZCwgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgZGF0ZV9hc2RhdGUpICU+JSBzdW1tYXJpemVfaWYoaXMubnVtZXJpYywgbWVkaWFuLCBuYS5ybT1UKSAlPiUgZHBseXI6OnNlbGVjdCgtZW5kc193aXRoKCJfZmQiKSkgJT4lICN3ZSB0YWtlIHRoZSBtZWRpYW4gYWNyb3NzIG9ic2VydmF0aW9ucwogICAgICAgICAgICAgICAgICAgbXV0YXRlKENGUj1kZWF0aHMvY29uZmlybWVkKQojZGltKGxoc19sb25nX21lZGlhbikKI3N1bW1hcnkobGhzX2xvbmdfbWVkaWFuKQpgYGAKCkhlcmUgd2UgZG8gdGhlIGFjdHVhbCBpbnRlcnBvbGF0aW9uLiBGb3IgZWFjaCBpbmRpdmlkdWFsIGxvY2F0aW9uLWRhdGFzZXQsIHdlIGZpdCBhIHBpZWNld2lzZSBsaW5lYXIgbW9kZWwgb3ZlciB0aW1lLCBhbmQgdGhlbiB1c2UgdGhhdCB0byBhdmVyYWdlIG92ZXIgZGF5IHRvIGRheSBub2lzZSBhbmQgaW50ZXJwb2xhdGUgYmV0d2VlbiBvYnNlcnZhdGlvbnMuIEJlY2F1c2UgdGhpcyBpcyBpbiBsb2cgc3BhY2UsIHRoZSBzbG9wZSBvZiB0aGF0IGxpbmUgaXMgdGhlIGRheSBvbiBkYXkgcGVyY2VudCBpbmNyZWFzZSBpbiB0aGUgY291bnQuIFdlIGZpbmlzaCBieSBmaXR0aW5nIGEgcGllY2V3aXNlIGludGVyY2VwdCBtb2RlbCB0byB0aG9zZSBzbG9wZXMgdG8gZ2V0IGEgc2luZ2xlIGRhaWx5IGVzdGltYXRlIG9mIGhvdyBtdWNoIHRoZSBjb3VudCBpcyBpbmNyZWFzaW5nLiBEYXRhc2V0cyBhcmUgYWJsZSB0byBkaXNhZ3JlZSBpbiBsb3RzIG9mIGRpZmZlcmVudCB3YXlzIGFuZCB3ZSBzdGlsbCByZWNvdmVyIGEgY29ycmVjdCByYXRlIG9mIGNoYW5nZS4KCiMjIEludGVycG9sYXRpb24gb2YgQ291bnRzCgpUbyBlYWNoIGluZGl2aWR1YWwgZGF0YXNldC1sb2NhdGlvbiBzZXJpZXMsIHdlIGZpdCBhIHBpZWNld2lzZSBsaW5lYXIgdHJlbmQuIEVhY2ggc2VnbWVudCBpcyByZXF1aXJlZCB0byBoYXZlIGF0IGxlYXN0IDMgb2JzZXJ2YXRpb25zLCBidXQgb3RoZXJ3aXNlIHdlIG1ha2Ugbm8gb3RoZXIgY29uc3RyYWludHMuIFRoaXMgYWxsb3dzIHVzIHRvIGZsZXhpYmx5IGZpdCBsaW5lYXIgc2VnbWVudHMgYXMgd2VsbCBhcyB0aWdodCBjdXJ2ZXMuIFdlIGFsc28gYWxsb3cgZm9yIHN0cnVjdHVyYWwgYnJlYWtzIHdoZXJlIHRoZSBzZXJpZXMgc3RvcHMsIGhhcyBhIHN0cnVjdHVyYWwgc2hpZnQgdXAgb3IgZG93biBiZWNhdXNlIHNheSBhIGNoYW5nZSBpbiByZXBvcnRpbmcgcnVsZXMsIGJ1dCBvdGhlciB0aGVuIG90aGVyd2lzZSBjb250aW51ZXMgYXMgbm9ybWFsLiBXZSB0YWtlIHRoZSBsaW5lYXIgdHJlbmQgZml0IGFzIG91ciBiZXN0IGVzdGltYXRlIGF0IGVhY2ggcG9pbnQuIFRoaXMgYXZlcmFnZXMgb3ZlciBkYXkgdG8gZGF5IG5vaXNlLCBlLmcuIHVuZGVyIHJlcG9ydGluZyBvbiB0aGUgd2Vla2VuZC4gSXQgYWxzbyBhbGxvd3MgdXMgdG8gaW50ZXJwb2xhdGUgYmV0d2VlbiBvYnNlcnZhdGlvbnMgd2hlcmUgdGhlcmUgaXMgbWlzc2luZ25lc3MgaW4gdGhlIHNlcmllcyBidXQgd2UgaGF2ZSByZWFzb25hYmxlIGJlbGllZnMgdGhlIHRydWUgbWVhc3VyZSBjb250aW51ZWQgbGluZWFybHkgYmV0d2VlbiB0aGUgb2JzZXJ2ZWQgcG9pbnRzLgoKYGBge3Isd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQoKI3dlIG5lZWQgdG8gcGFyYWxsZWxpemUgdGhpcyBjb2RlIGFuZCBzZWUgd2hhdCdzIGxvdWRseSB0aHJvd2luZwojRXJyb3IgaW4gY2hvbC5kZWZhdWx0KEoxMikgOiAKIyAgdGhlIGxlYWRpbmcgbWlub3Igb2Ygb3JkZXIgMSBpcyBub3QgcG9zaXRpdmUgZGVmaW5pdGUKCmRhdGFzZXRfcGxhY2VzIDwtIGxoc19sb25nX2NsZWFuICU+JSBkcGx5cjo6c2VsZWN0KGRhdGFzZXRfZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCkgJT4lIGRpc3RpbmN0KCkgJT4lIHB1bGwoZGF0YXNldF9naWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkKQpsaWJyYXJ5KHBhcnR5KQp0ZW1wX2xpc3QxIDwtIGxpc3QoKQpvcHRpb25zKGVycm9yID0gZXhwcmVzc2lvbihOVUxMKSkKc2luayhOVUxMKQp6eiA8LSBmaWxlKCJtZXNzYWdlcy50eHQiLCBvcGVuID0gInd0IikKc2luayh6eikKc3VwcHJlc3NNZXNzYWdlcygKZm9yKHEgaW4gZGF0YXNldF9wbGFjZXMgICl7CiAgICAgICN0cnkoewogICAgICAgIHRlbXAgPC0gTlVMTAogICAgICAgIHRlbXAgPC0gbGhzX2xvbmdfY2xlYW4gJT4lCiAgICAgICAgICAgICAgICBmaWx0ZXIoZGF0YXNldF9naWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkICVpbiUgcSkgJT4lCiAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUKCiAgICAgICAgICAgICAgICBtdXRhdGUoY29uZmlybWVkX2xvZz1sb2coY29uZmlybWVkKSkgJT4lCiAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX2xvZz1sb2coZGVhdGhzKSkgJT4lCiAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3Blb3BsZV9sb2c9bG9nKHRlc3RlZF9wZW9wbGUpKSAlPiUKICAgICAgICAgICAgICAgIG11dGF0ZSh0ZXN0ZWRfc2FtcGxlc19sb2c9bG9nKHRlc3RlZF9zYW1wbGVzKSkgCiAgICAgICAgICAKICAgICAgICBpZihucm93KHRlbXApPT0wKXtuZXh0KCl9CiAgICAgICAgCiAgICAgICAgdGVtcCA8LSB0ZW1wICU+JSBleHBhbmQoZGF0YXNldCwgZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCwgZ2lkLCBnZW9uYW1laWQsd2lraWRhdGFfaWQsIGRhdGVfYXNkYXRlPW1pbihkYXRlX2FzZGF0ZSk6bWF4KGRhdGVfYXNkYXRlKSAlPiUgYXNfZGF0ZSgpICkgJT4lIAogICAgICAgICAgICAgICAgIGZ1bGxfam9pbih0ZW1wKSAlPiUgCiAgICAgICAgICAgICAgICAgbXV0YXRlKGRhdGVfYXNudW1lcmljPSBhcy5udW1lcmljKGRhdGVfYXNkYXRlKSApICU+JSAKICAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNudW1lcmljKSAlPiUKICAgICAgICAgICAgICAgICBtdXRhdGUoY29uZmlybWVkX25vbm1pc3NpbmdfY291bnQgICAgID0gKCFpcy5uYShjb25maXJtZWQpKSAlPiUgY3Vtc3VtKCkgKSAlPiUKICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX25vbm1pc3NpbmdfY291bnQgICAgID0gKCFpcy5uYShkZWF0aHMpKSAlPiUgY3Vtc3VtKCkgKSAlPiUKICAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3Blb3BsZV9ub25taXNzaW5nX2NvdW50ICAgICA9ICghaXMubmEodGVzdGVkX3Blb3BsZSkpICU+JSBjdW1zdW0oKSApICU+JQogICAgICAgICAgICAgICAgIG11dGF0ZSh0ZXN0ZWRfc2FtcGxlc19ub25taXNzaW5nX2NvdW50ICAgICA9ICghaXMubmEodGVzdGVkX3NhbXBsZXMpKSAlPiUgY3Vtc3VtKCkgKSAlPiUKICAgICAgICAKICAgICAgICAgICAgICAgICBhcnJhbmdlKC1kYXRlX2FzbnVtZXJpYykgJT4lCiAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9ub25taXNzaW5nX2NvdW50X3JldmVyc2VkICAgICA9ICghaXMubmEoY29uZmlybWVkKSkgJT4lIGN1bXN1bSgpICkgJT4lCiAgICAgICAgICAgICAgICAgbXV0YXRlKGRlYXRoc19ub25taXNzaW5nX2NvdW50X3JldmVyc2VkICAgICA9ICghaXMubmEoZGVhdGhzKSkgJT4lIGN1bXN1bSgpICkgJT4lCiAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbm9ubWlzc2luZ19jb3VudF9yZXZlcnNlZCAgICAgPSAoIWlzLm5hKHRlc3RlZF9wZW9wbGUpKSAlPiUgY3Vtc3VtKCkgKSAlPiUKICAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3NhbXBsZXNfbm9ubWlzc2luZ19jb3VudF9yZXZlcnNlZCAgICAgPSAoIWlzLm5hKHRlc3RlZF9zYW1wbGVzKSkgJT4lIGN1bXN1bSgpICkgJT4lIAogICAgICAgICAgICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpIAoKICAgICAgICB0cnlDYXRjaCh7ICAKICAgICAgICAgIGlmKHN1bSghaXMubmEodGVtcCRjb25maXJtZWRfbG9nKSk+PTMpeyAjbmVlZCBhdCBsZWFzdCAzIHBvaW50cwogICAgICAgICAgICB0cmVlX2NvbmZpcm1lZCA8LSBwYXJ0eTo6bW9iKGNvbmZpcm1lZF9sb2cgfiAxICsgZGF0ZV9hc251bWVyaWMgICAgfCBkYXRlX2FzbnVtZXJpYyAsIGNvbnRyb2wgPSBtb2JfY29udHJvbChtaW5zcGxpdCA9IDMsIGFscGhhPS4yKSwgZGF0YSA9IHRlbXAsICBtb2RlbCA9IGxpbmVhck1vZGVsKSAgIyArIEkoZGF0ZV9hc251bWVyaWNeMikgIAogICAgICAgICAgICB0ZW1wJGNvbmZpcm1lZF9sb2dfeV9oYXQgPC0gcHJlZGljdCggdHJlZV9jb25maXJtZWQsIG5ld2RhdGE9dGVtcCAsIHR5cGUgPSBjKCJyZXNwb25zZSIpICkKICAgICAgICAgICAgdGVtcCRjb25maXJtZWRfbG9nX2dyb3VwX251bWJlciA8LSAgcHJlZGljdCggdHJlZV9jb25maXJtZWQsIG5ld2RhdGE9dGVtcCAsIHR5cGUgPSBjKCJub2RlIikpCiAgICAgICAgICAgIHRlbXAgPC0gdGVtcCAlPiUgCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2dfeV9oYXQgICAgICAgPWlmZWxzZShjb25maXJtZWRfbm9ubWlzc2luZ19jb3VudD4wICYgY29uZmlybWVkX25vbm1pc3NpbmdfY291bnRfcmV2ZXJzZWQ+MCxjb25maXJtZWRfbG9nX3lfaGF0LE5BKSkgJT4lICNvbmx5IGludGVycG9sYXRlIHdpdGhpbiB0aGUgb2JzZXJ2ZWQgZGF0YSwgbmV2ZXIgYmVmb3JlIG9yIGFmdGVyCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyPWlmZWxzZShjb25maXJtZWRfbm9ubWlzc2luZ19jb3VudD4wICYgY29uZmlybWVkX25vbm1pc3NpbmdfY291bnRfcmV2ZXJzZWQ+MCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcixOQSkpICU+JSAjb25seSBpbnRlcnBvbGF0ZSB3aXRoaW4gdGhlIG9ic2VydmVkIGRhdGEsIG5ldmVyIGJlZm9yZSBvciBhZnRlcgoKICAgICAgICAgICAgICAgICAgICBncm91cF9ieShjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikgJT4lCiAgICAgICAgICAgICAgICAgICAgYXJyYW5nZShkYXRlX2FzbnVtZXJpYykgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2dfeV9oYXRfc2xvcGU9dHNpYmJsZTo6ZGlmZmVyZW5jZShjb25maXJtZWRfbG9nX3lfaGF0KSkgJT4lIAogICAgICAgICAgICAgICAgICAgIGZpbGwoY29uZmlybWVkX2xvZ195X2hhdF9zbG9wZSwgLmRpcmVjdGlvbj0idXAiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gcm91bmQoKGV4cChjb25maXJtZWRfbG9nX3lfaGF0X3Nsb3BlKS0xKSoxMDAsMikpICAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoY29uZmlybWVkX2xvZ195X2hhdD1pZmVsc2UoY29uZmlybWVkX2xvZ195X2hhdDwwLE5BLCBjb25maXJtZWRfbG9nX3lfaGF0KSkKICAgICAgICAgIH0KICAgICAgICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHt9LCBzaWxlbnQ9VFJVRSkKICAgICAgICAKICAgICAgICB0cnlDYXRjaCh7ICAKICAgICAgICAgIGlmKHN1bSghaXMubmEodGVtcCRkZWF0aHNfbG9nKSk+PTMpeyAjbmVlZCBhdCBsZWFzdCAzIHBvaW50cwogICAgICAgICAgICB0cmVlX2RlYXRocyA8LSBwYXJ0eTo6bW9iKGRlYXRoc19sb2cgfiAxICsgZGF0ZV9hc251bWVyaWMgICAgfCBkYXRlX2FzbnVtZXJpYyAsIGNvbnRyb2wgPSBtb2JfY29udHJvbChtaW5zcGxpdCA9IDMsIGFscGhhPS4yKSwgZGF0YSA9IHRlbXAsICBtb2RlbCA9IGxpbmVhck1vZGVsKSAgIyArIEkoZGF0ZV9hc251bWVyaWNeMikgICAgCiAgICAgICAgICAgIHRlbXAkZGVhdGhzX2xvZ195X2hhdCA8LSBwcmVkaWN0KCB0cmVlX2RlYXRocywgbmV3ZGF0YT10ZW1wICwgdHlwZSA9IGMoInJlc3BvbnNlIikgKQogICAgICAgICAgICB0ZW1wJGRlYXRoc19sb2dfZ3JvdXBfbnVtYmVyIDwtICBwcmVkaWN0KCB0cmVlX2RlYXRocywgbmV3ZGF0YT10ZW1wICwgdHlwZSA9IGMoIm5vZGUiKSkKICAgICAgICAgICAgdGVtcCA8LSB0ZW1wICU+JSAKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX2xvZ195X2hhdD1pZmVsc2UoZGVhdGhzX25vbm1pc3NpbmdfY291bnQ+MCAmIGRlYXRoc19ub25taXNzaW5nX2NvdW50X3JldmVyc2VkPjAsZGVhdGhzX2xvZ195X2hhdCxOQSkpICU+JSAjb25seSBpbnRlcnBvbGF0ZSB3aXRoaW4gdGhlIG9ic2VydmVkIGRhdGEsIG5ldmVyIGJlZm9yZQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfbG9nX2dyb3VwX251bWJlcj1pZmVsc2UoZGVhdGhzX25vbm1pc3NpbmdfY291bnQ+MCAmIGRlYXRoc19ub25taXNzaW5nX2NvdW50X3JldmVyc2VkPjAsZGVhdGhzX2xvZ19ncm91cF9udW1iZXIsTkEpKSAlPiUgI29ubHkgaW50ZXJwb2xhdGUgd2l0aGluIHRoZSBvYnNlcnZlZCBkYXRhLCBuZXZlciBiZWZvcmUKCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoZGVhdGhzX2xvZ19ncm91cF9udW1iZXIpICU+JSAKICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNudW1lcmljKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGRlYXRoc19sb2dfeV9oYXRfc2xvcGU9dHNpYmJsZTo6ZGlmZmVyZW5jZShkZWF0aHNfbG9nX3lfaGF0KSkgJT4lCiAgICAgICAgICAgICAgICAgICAgZmlsbChkZWF0aHNfbG9nX3lfaGF0X3Nsb3BlLCAuZGlyZWN0aW9uPSJ1cCIpICU+JQogICAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IHJvdW5kKChleHAoZGVhdGhzX2xvZ195X2hhdF9zbG9wZSktMSkqMTAwLDIpKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX2xvZ195X2hhdD1pZmVsc2UoZGVhdGhzX2xvZ195X2hhdDwwLE5BLCBkZWF0aHNfbG9nX3lfaGF0KSkgI3JlamVjdCBhbnkgd2hlcmUgdGhlIHByZWRpY3Rpb24gaXMgbGVzcyB0aGFuIDEgZnVsbCBjYXNlCiAgICAgICAgICB9CiAgICAgICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7fSwgc2lsZW50PVRSVUUpCiAgICAgICAgCiAgICAgICAgdHJ5Q2F0Y2goeyAgCiAgICAgICAgICBpZihzdW0oIWlzLm5hKHRlbXAkdGVzdGVkX3Blb3BsZV9sb2cpKT49Myl7ICNuZWVkIGF0IGxlYXN0IDMgcG9pbnRzCiAgICAgICAgICAgIHRyZWVfdGVzdGVkX3Blb3BsZSA8LSBwYXJ0eTo6bW9iKHRlc3RlZF9wZW9wbGVfbG9nIH4gMSArIGRhdGVfYXNudW1lcmljICAgIHwgZGF0ZV9hc251bWVyaWMgLCBjb250cm9sID0gbW9iX2NvbnRyb2wobWluc3BsaXQgPSAzLCBhbHBoYT0uMiksIGRhdGEgPSB0ZW1wLCAgbW9kZWwgPSBsaW5lYXJNb2RlbCkgICMgKyBJKGRhdGVfYXNudW1lcmljXjIpICAgCiAgICAgICAgICAgIHRlbXAkdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQgPC0gcHJlZGljdCggdHJlZV90ZXN0ZWRfcGVvcGxlLCBuZXdkYXRhPXRlbXAgLCB0eXBlID0gYygicmVzcG9uc2UiKSApCiAgICAgICAgICAgIHRlbXAkdGVzdGVkX3Blb3BsZV9sb2dfZ3JvdXBfbnVtYmVyIDwtICBwcmVkaWN0KCB0cmVlX3Rlc3RlZF9wZW9wbGUsIG5ld2RhdGE9dGVtcCAsIHR5cGUgPSBjKCJub2RlIikpCiAgICAgICAgICAgIHRlbXAgPC0gdGVtcCAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0PWlmZWxzZSh0ZXN0ZWRfcGVvcGxlX25vbm1pc3NpbmdfY291bnQ+MCAmIHRlc3RlZF9wZW9wbGVfbm9ubWlzc2luZ19jb3VudF9yZXZlcnNlZD4wLHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LE5BKSkgJT4lICNvbmx5IGludGVycG9sYXRlIHdpdGhpbiB0aGUgb2JzZXJ2ZWQgZGF0YSwgbmV2ZXIgYmVmb3JlCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nX2dyb3VwX251bWJlcj1pZmVsc2UodGVzdGVkX3Blb3BsZV9ub25taXNzaW5nX2NvdW50PjAgJiB0ZXN0ZWRfcGVvcGxlX25vbm1pc3NpbmdfY291bnRfcmV2ZXJzZWQ+MCx0ZXN0ZWRfcGVvcGxlX2xvZ19ncm91cF9udW1iZXIsTkEpKSAlPiUgI29ubHkgaW50ZXJwb2xhdGUgd2l0aGluIHRoZSBvYnNlcnZlZCBkYXRhLCBuZXZlciBiZWZvcmUKICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieSh0ZXN0ZWRfcGVvcGxlX2xvZ19ncm91cF9udW1iZXIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNudW1lcmljKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfc2xvcGU9dHNpYmJsZTo6ZGlmZmVyZW5jZSh0ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICBmaWxsKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3Nsb3BlLCAuZGlyZWN0aW9uPSJ1cCIpICU+JSB1bmdyb3VwKCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gcm91bmQoKGV4cCh0ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9zbG9wZSktMSkqMTAwLDIpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQ9aWZlbHNlKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0PDAsTkEsIHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0KSkgI3JlamVjdCBhbnkgd2hlcmUgdGhlIHByZWRpY3Rpb24gaXMgbGVzcyB0aGFuIDEgZnVsbCBjYXNlCiAgICAgICAgICB9CiAgICAgICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7fSwgc2lsZW50PVRSVUUpCiAgICAgICAgCiAgICAgICAgdGVtcF9saXN0MVtbcSBdXSA8LSB0ZW1wCiAgCiAgICAgICN9KQp9CikKc2luayhOVUxMKQpsaHNfbG9uZ19jbGVhbl9pbXB1dGVkMSA8LSBiaW5kX3Jvd3ModGVtcF9saXN0MSkKZGltKGxoc19sb25nX2NsZWFuX2ltcHV0ZWQxKSAjNTAwLDc4NiAjYmlnZ2VyIGJlY2F1c2Ugd2UncmUgaW50ZXJwb2xhdGluZyBub3cKCiNydDEgPC0gcnBhcnQoZm9ybXVsYSA9IGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiBkYXRlX2FzbnVtZXJpYywgZGF0YT10ZXN0KQojaW50ZXJwb2xhdGVkID0gZGF0YS5mcmFtZShkYXRlX2FzbnVtZXJpYz1taW4odGVzdCRkYXRlX2FzbnVtZXJpYyk6bWF4KHRlc3QkZGF0ZV9hc251bWVyaWMpICkKI2ludGVycG9sYXRlZCRjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0IDwtICBwcmVkaWN0KHJ0MSwgbmV3ZGF0YT1pbnRlcnBvbGF0ZWQpCiNpbnRlcnBvbGF0ZWQkZGF0ZV9hc2RhdGUgPC0gYXMuRGF0ZShpbnRlcnBvbGF0ZWQkZGF0ZV9hc251bWVyaWMpCgpwbGFjZXMgPC0gbGhzX2xvbmdfY2xlYW4gJT4lIGRwbHlyOjpzZWxlY3QoZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCkgJT4lIGRpc3RpbmN0KCkgJT4lIHB1bGwoZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCkKCmxpYnJhcnkocnBhcnQpCm1pbnNwbGl0PTYKbWluYnVja2V0PTMKdGVtcF9saXN0MiA8LSBsaXN0KCkKZm9yKHEgaW4gcGxhY2VzICl7CiAgcHJpbnQocSkKICB0ZW1wIDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQxICU+JSAKICAgICAgICAgICAgICAgICBmaWx0ZXIoZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCAlaW4lIHEpICU+JSAKICAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNudW1lcmljKSAKICAgIAogICAgICAgICAgCiAgdHJ5Q2F0Y2goeyAgCiAgICBydDEgPC0gcnBhcnQ6OnJwYXJ0KGZvcm11bGEgPSBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gZGF0ZV9hc251bWVyaWMsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9dGVtcCAlPiUgZmlsdGVyKCFpcy5uYShjb25maXJtZWRfbG9nKSksICN0byBrZWVwIGZyb20gZml0dGluZyB0byBpbnRlcnBvbGF0ZSBzbG9wZXMgdGhhdCBhcmUgb3V0IG9mIGRvbWFpbiBhbmQgdXN1YWxseSB3cm9uZywgcmVxdWlyZSBjb25maXJtZWQgdG8gbm90IGJlIG1pc3Npbmcgb3IgbmEKICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IHJwYXJ0LmNvbnRyb2wobWluc3BsaXQgPSBtaW5zcGxpdCwgbWluYnVja2V0PW1pbmJ1Y2tldCkpCiAgICB0ZW1wJGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgPC0gIHByZWRpY3QocnQxLCBuZXdkYXRhPXRlbXApICN0aGlzIHByZWRpY3Rpb24gaGVscGZ1bGx5IHRyaWVzIHRvIGltcHV0ZSBiYWNrd2FyZHMgZXZlbiBiZWZvcmUgdGhlcmUgYXJlIGFueSBkYXkgaW4gYW55IHNlcmllcwogICAgI1dlIG5lZWQgdG8gbnVrZSBpdCBpZiBubyBkYXRhIGV4aXN0CiAgICB0ZW1wIDwtIHRlbXAgJT4lCiAgICAgICAgICAgIGdyb3VwX2J5KGRhdGVfYXNkYXRlKSAlPiUKICAgICAgICAgICAgbXV0YXRlKCBjb25maXJtZWRfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0cz1zdW0oY29uZmlybWVkX25vbm1pc3NpbmdfY291bnQ+MCxuYS5ybT1UKSApICU+JQogICAgICAgICAgICBtdXRhdGUoIGNvbmZpcm1lZF9ub25taXNzaW5nX2NvdW50X2RhdGFzZXRzX3JldmVyc2VkPXN1bShjb25maXJtZWRfbm9ubWlzc2luZ19jb3VudF9yZXZlcnNlZD4wLG5hLnJtPVQpICkgJT4lCiAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0PWlmZWxzZShjb25maXJtZWRfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0cz4wICYgY29uZmlybWVkX25vbm1pc3NpbmdfY291bnRfZGF0YXNldHNfcmV2ZXJzZWQ+MCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0LE5BKSkgICU+JQogICAgICB1bmdyb3VwKCkKICAgIAogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkge30pCiAgCiAgdHJ5Q2F0Y2goeyAgCiAgICBydDIgPC0gcnBhcnQ6OnJwYXJ0KGZvcm11bGEgPSBkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gZGF0ZV9hc251bWVyaWMsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9dGVtcCAlPiUgZmlsdGVyKCFpcy5uYShkZWF0aHNfbG9nKSksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBycGFydC5jb250cm9sKG1pbnNwbGl0ID0gbWluc3BsaXQsIG1pbmJ1Y2tldD1taW5idWNrZXQpKQogICAgdGVtcCRkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0IDwtICBwcmVkaWN0KHJ0MiwgbmV3ZGF0YT10ZW1wKQogICAgdGVtcCA8LSB0ZW1wICU+JQogICAgICAgIGdyb3VwX2J5KGRhdGVfYXNkYXRlKSAlPiUKICAgICAgICBtdXRhdGUoIGRlYXRoc19ub25taXNzaW5nX2NvdW50X2RhdGFzZXRzPXN1bShkZWF0aHNfbm9ubWlzc2luZ19jb3VudD4wLG5hLnJtPVQpICkgJT4lCiAgICAgICAgbXV0YXRlKCBkZWF0aHNfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0c19yZXZlcnNlZD1zdW0oZGVhdGhzX25vbm1pc3NpbmdfY291bnRfcmV2ZXJzZWQ+MCxuYS5ybT1UKSApICU+JQogICAgICAgIG11dGF0ZShkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0PWlmZWxzZShkZWF0aHNfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0cz4wICYgZGVhdGhzX25vbm1pc3NpbmdfY291bnRfZGF0YXNldHNfcmV2ZXJzZWQ+MCxkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0LE5BKSkgJT4lCiAgICAgIHVuZ3JvdXAoKQogICAgICAgIAogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkge30pCgogIHRyeUNhdGNoKHsgIAogICAgcnQzIDwtIHJwYXJ0OjpycGFydChmb3JtdWxhID0gdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiBkYXRlX2FzbnVtZXJpYywKICAgICAgICAgICAgICAgICAgICBkYXRhPXRlbXAgJT4lIGZpbHRlcighaXMubmEodGVzdGVkX3Blb3BsZV9sb2cpKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gcnBhcnQuY29udHJvbChtaW5zcGxpdCA9IG1pbnNwbGl0LCBtaW5idWNrZXQ9bWluYnVja2V0KSkKICAgIHRlbXAkdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgPC0gIHByZWRpY3QocnQzLCBuZXdkYXRhPXRlbXAsIGNvbnRyb2wgPSBycGFydC5jb250cm9sKG1pbnNwbGl0ID0gbWluc3BsaXQsIG1pbmJ1Y2tldD1taW5idWNrZXQpKQogICAgdGVtcCA8LSB0ZW1wICU+JQogICAgICAgIGdyb3VwX2J5KGRhdGVfYXNkYXRlKSAlPiUKICAgICAgICBtdXRhdGUoIHRlc3RlZF9wZW9wbGVfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0cz1zdW0odGVzdGVkX3Blb3BsZV9ub25taXNzaW5nX2NvdW50PjAsbmEucm09VCkgKSAlPiUKICAgICAgICBtdXRhdGUoIHRlc3RlZF9wZW9wbGVfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0c19yZXZlcnNlZD1zdW0odGVzdGVkX3Blb3BsZV9ub25taXNzaW5nX2NvdW50X3JldmVyc2VkPjAsbmEucm09VCkgKSAlPiUKICAgICAgCiAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0PWlmZWxzZSh0ZXN0ZWRfcGVvcGxlX25vbm1pc3NpbmdfY291bnRfZGF0YXNldHM+MCAmIHRlc3RlZF9wZW9wbGVfbm9ubWlzc2luZ19jb3VudF9kYXRhc2V0c19yZXZlcnNlZD4wLHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0LE5BKSkgICU+JQogICAgICB1bmdyb3VwKCkKICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHt9KQogIAogIHRlbXBfbGlzdDJbW3EgXV0gPC0gdGVtcAp9Cmxoc19sb25nX2NsZWFuX2ltcHV0ZWQyIDwtIGJpbmRfcm93cyh0ZW1wX2xpc3QyKQoKbGhzX2xvbmdfY2xlYW5faW1wdXRlZCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkMgpkaW0obGhzX2xvbmdfY2xlYW5faW1wdXRlZCkgIzYyOSw0OTMgIzQxOTkxMCAjNDEzNDc1ICM0MDgsMzY5ICN3ZSBsb3NlIGFueXdpdGhvdXQgcSBjb2RlcyBoZXJlCnNhdmVSRFMobGhzX2xvbmdfY2xlYW5faW1wdXRlZCwgIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2xoc19sb25nX2NsZWFuX2ltcHV0ZWQuUmRzIikKCmBgYAoKIyMjIEV4YW1wbGVzCgojIyMjIENoaW5hCgpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CiNDaGluYQojIlExNDgiCgp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTE0OCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKcF9pbnRlcnBvbGF0aW9uMCA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJDaGluYSBRMTQ4IENvbmZpcm1lZCIpICsgZmFjZXRfd3JhcCh+ZGF0YXNldCAgICkKCmBgYAoKRGF0YSBvbiBDaGluYSBzaG93cyB2YXJpYXRpb24gYWNyb3NzIGRhdGFzZXRzIGZvciB3aGVuIHRoZXkgc3RhcnQgbWVhc3VyaW5nLiBPbmx5IHR3byBvYnNlcnZlIHRoZSB2ZXJ5IGJlZ2lubmluZyBvZiB0aGUgb3V0YnJlYWsuIEFsbCBvZiB0aGUgZGF0YXNldHMgc2hvdyBhIGRpc2NvbnRpbnVpdHkgd2hlcmUgcmVwb3J0aW5nIHN0YW5kYXJkcyBtdXN0IGhhdmUgY2hhbmdlZC4gT3VyIG1ldGhvZCBhdHRlbXB0cyB0byBicmlkZ2UgdGhhdCBnYXAgaW4gMyBvZiB0aGUgc2VyaWVzIGJ1dCBub3QgdHdvIG90aGVycy4KCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KcF9pbnRlcnBvbGF0aW9uMApgYGAKIyMjIyBJdGFseSAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KI0l0YWx5CiMiUTM4IgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlEzOCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKcF9pbnRlcnBvbGF0aW9uMSA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJJdGFseSBRMzggQ29uZmlybWVkIikgKyBmYWNldF93cmFwKH5kYXRhc2V0ICAgKQoKYGBgCgpJdGFseSBsaWtld2lzZSBzaG93cyB2YXJpYXRpb24gaW4gdGhlIHN0YXJ0IG9mIHJlY29yZGluZyBhY3Jvc3MgZGF0YXNldHMuIFRoZXJlJ3MgYWxzbyB2YXJpYXRpb24gaW4gdGhlIGluaXRpYWwgc3BhcmNpdHkuIFdpa2lwZWRpYSBpcyBzdHJhbmdlbHkgbWlzc2luZyBkYXRhIGluIHRoZSBtaWRkbGUuIE91ciBtZXRob2QgbGluZWFybHkgaW50ZXJwb2xhdGVzIGludG8gdGhhdCBzcGFjZSBpbiBhIHdheSBpbiBhIHdheSB3ZSBwcm9iYWJseSBkb24ndCB3YW50LgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQpwX2ludGVycG9sYXRpb24xCmBgYAoKIyMjIyBJdGFseSAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KI1VTCiMiUTMwIgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlEzMCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKcF9pbnRlcnBvbGF0aW9uMiA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJVUyBRMzAgQ29uZmlybWVkIikgKyBmYWNldF93cmFwKH5kYXRhc2V0ICAgKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQpwX2ludGVycG9sYXRpb24yCmBgYAoKCiMjIyMgTmV3IFlvcmsgU3RhdGUKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KI1VTCiMiUTMwIgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlExMzg0IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgpwX2ludGVycG9sYXRpb24zIDwtIHRlc3QgJT4lCiAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICAgICAgICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoIk5ldyBZb3JrIFN0YXRlIFExMzg0IENvbmZpcm1lZCIpICsgZmFjZXRfd3JhcCh+ZGF0YXNldCAgICkKCmBgYAoKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KcF9pbnRlcnBvbGF0aW9uMwpgYGAKCiMjIyMgTmV3IFlvcmsgQ2l0eSAoYnkgY291bnR5KQoKbnl0IGhhcyBpdCBqdXN0IGJ5IGNpdHksIGl0IGRvZXNuJ3QgYnJlYWsgaXQgZG93biBieSB0aGUgYm9yb3VnaHMuIEJ1dCBiZWNhdXNlIGdhZG0gZG9lc24ndCBkbyBjaXRpZXMgd2UgZG9uJ3QgYXNzaWduIGl0IGEgcWNvZGUuCgp1c2FmYWN0cyBoYXMgaXQgYXMgTmV3IFlvcmsgQ291bnR5IHdoaWNoIGlzIE5ldyBZb3JrIENvdW50eSAoTWFuaGF0dGFuKQoKYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojQnJvb2tseW4gKFExODQxOSkKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlE4NTU5NzQiKSAlPiUgICNubyBoaXRzPwogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgpwX2ludGVycG9sYXRpb240YSA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJCcm9ueCBDb3VudHkgKFE4NTU5NzQpIikgKyBmYWNldF93cmFwKH5kYXRhc2V0ICAgKSArIGd1aWRlcyggY29sb3IgPSBGQUxTRSkKCiNRdWVlbnMgQ291bnR5LCBOZXcgWW9yayBRNTE0MjU1OQp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTUxNDI1NTkiKSAlPiUgICNubyBoaXRzPwogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgpwX2ludGVycG9sYXRpb240YiA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJRdWVlbnMgQ291bnR5LCBOZXcgWW9yayBRNTE0MjU1OSIpICsgZmFjZXRfd3JhcCh+ZGF0YXNldCAgICkgKyBndWlkZXMoIGNvbG9yID0gRkFMU0UpCgojQnJvb2tseW4gaXMgYXBhcmVudGx5IEtpbmdzIENvdW50eSBRMTE5ODA2OTIKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlExMTk4MDY5MiIpICU+JSAgI25vIGhpdHM/CiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCnBfaW50ZXJwb2xhdGlvbjRjIDwtIHRlc3QgJT4lCiAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICAgICAgICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoIkJyb29rbHluIGlzIEtpbmdzIENvdW50eSBRMTE5ODA2OTIiKSArIGZhY2V0X3dyYXAofmRhdGFzZXQgICApICsgZ3VpZGVzKCBjb2xvciA9IEZBTFNFKQoKIyBNYW5oYXR0YW4gaXMgTmV3IFlvcmsgQ291bnR5IFE1MDA0MTYKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlE1MDA0MTYiKSAlPiUgICNubyBoaXRzPwogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgpwX2ludGVycG9sYXRpb240ZCA8LSB0ZXN0ICU+JQogICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJNYW5oYXR0YW4gaXMgTmV3IFlvcmsgQ291bnR5IFE1MDA0MTYiKSArIGZhY2V0X3dyYXAofmRhdGFzZXQgICApICsgZ3VpZGVzKCBjb2xvciA9IEZBTFNFKQoKI1N0YXRlbiBJc2xhbmQgaXMgcmljaG1vbmQgY291bnR5IFExMTk5Nzc4NAp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTExOTk3Nzg0IikgJT4lICAjbm8gaGl0cz8KICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKcF9pbnRlcnBvbGF0aW9uNGUgPC0gdGVzdCAlPiUKICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgICAgICAgICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZSgiU3RhdGVuIElzbGFuZCAgUmljaG1vbmQgQ291bnR5IFExMTk5Nzc4NCIpICsgZmFjZXRfd3JhcCh+ZGF0YXNldCAgICkgKyBndWlkZXMoIGNvbG9yID0gRkFMU0UpCgpgYGAKCk5vdGUgdGhhdCBDU1NFIGlzIGNvbmZsYXRpbmcgYWxsIG9mIE5ldyBZb3JrIENpdHkgd2l0aCBNYW5oYXR0YW4vTmV3IFlvcmsgQ291bnR5LCBCaW5nIGlzIHRvbyBJIHRoaW5rCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CnBfaW50ZXJwb2xhdGlvbjRhICsgcF9pbnRlcnBvbGF0aW9uNGIgKyBwX2ludGVycG9sYXRpb240YyArIHBfaW50ZXJwb2xhdGlvbjRkICsgcF9pbnRlcnBvbGF0aW9uNGUKYGBgCgoKCiMjIFBsb3RzIGJ5IENvdW50cmllcwoKYGBge3J9CmxpYnJhcnkoZGF0YS50YWJsZSkKZ2VvbmFtZXMgPC0gZnJlYWQoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2FsbENvdW50cmllcy50eHQiLCBzZXA9Ilx0IikgJT4lIG11dGF0ZV9pZihpcy5udW1lcmljLGFzLmNoYXJhY3RlcikgJT4lIG11dGF0ZV9pZihpcy5mYWN0b3IsYXMuY2hhcmFjdGVyKQpkaW0oZ2VvbmFtZXMpICMxMiwwMDYsNDI2CgpnZW9uYW1lc19zbWFsbCA8LSBnZW9uYW1lcyAlPiUgZHBseXI6OnNlbGVjdChnZW9uYW1laWQ9VjEsIG5hbWVfdGV4dD1WMikgJT4lIGlubmVyX2pvaW4oIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIGRwbHlyOjpzZWxlY3QoZ2VvbmFtZWlkKSAlPiUgZGlzdGluY3QoKSApCmRpbShnZW9uYW1lc19zbWFsbCkKCmBgYAoKIyMjIENvbmZpcm1lZApgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnBfY29uZmlybWVkX2J5X2NvdW50cnkgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIWdpZCAlPiUgc3RyX2RldGVjdCgiXyIpICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKGdlb25hbWVzX3NtYWxsICApICU+JSBtdXRhdGUobmFtZV90ZXh0ICU+JSBhcy5mYWN0b3IoKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGdpZF9nZW9uYW1laWRfd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICNnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoIkNvbmZpcm1lZCAobG9nKSBieSBDb3VudHJ5IikgKyBmYWNldF93cmFwKH5uYW1lX3RleHQgICApICsgZ3VpZGVzKCBjb2xvciA9IEZBTFNFKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKYGBge3J9CnBfY29uZmlybWVkX2J5X2NvdW50cnkKYGBgCgojIyMgRGVhdGhzCgpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnBfZGVhdGhzX2J5X2NvdW50cnkgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIWdpZCAlPiUgc3RyX2RldGVjdCgiXyIpICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKGdlb25hbWVzX3NtYWxsICApICU+JSBtdXRhdGUobmFtZV90ZXh0ICU+JSBhcy5mYWN0b3IoKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGdpZF9nZW9uYW1laWRfd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICNnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoIkRlYXRocyAobG9nKSBieSBDb3VudHJ5IikgKyBmYWNldF93cmFwKH5uYW1lX3RleHQgICApICsgZ3VpZGVzKCBjb2xvciA9IEZBTFNFKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMn0KcF9kZWF0aHNfYnlfY291bnRyeQpgYGAKCiMjIyBUZXN0cwoKYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpwX3Rlc3RlZF9wZW9wbGVfYnlfY291bnRyeSA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighZ2lkICU+JSBzdHJfZGV0ZWN0KCJfIikgKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0X2pvaW4oZ2VvbmFtZXNfc21hbGwgICkgJT4lIG11dGF0ZShuYW1lX3RleHQgJT4lIGFzLmZhY3RvcigpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZ2lkX2dlb25hbWVpZF93aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2dlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJUZXN0cyAobG9nKSBieSBDb3VudHJ5IikgKyBmYWNldF93cmFwKH5uYW1lX3RleHQgICApICsgZ3VpZGVzKCBjb2xvciA9IEZBTFNFKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMn0KcF90ZXN0ZWRfcGVvcGxlX2J5X2NvdW50cnkKYGBgCgoKIyMgSW50ZXJwb2xhdGlvbiBvZiBSYXRlIG9mIENoYW5nZQoKIyMgUGxvdCBDb25maXJtZWQgQ3VydmVzIGZvciBTZWxlY3QgTG9jYXRpb25zCgpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CgpsaWJyYXJ5KHBhdGNod29yaykKbGhzX2xvbmdfY2xlYW5faW1wdXRlZCA8LSByZWFkUkRTKCAiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTY292aWQxOS9kYXRhX3RlbXAvbGhzX2xvbmdfY2xlYW5faW1wdXRlZC5SZHMiKQpkaW0obGhzX2xvbmdfY2xlYW5faW1wdXRlZCkgIzQ1LDYwOSAjMzM3MDQzCgojd2Ugd2FudCB0aGUgY29sb3JzIHRvIGJlIGNvbnNpc3RlbnQgYnkgZGF0YXNldCB0b28gYnR3CgojIyMjIwojVVNBIFEzMAoKI2JwX3RlbXAgPC0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT10ZW1wX2RmICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlEzMCIpKQojY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZT1maXR0ZWQudmFsdWVzKGJwX3RlbXApCgp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMzAiKSAlPiUgCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgICU+JQogICAgICAgIG11dGF0ZShkYXRlX2FzbnVtZXJpYyA9IGRhdGVfYXNkYXRlICU+JSBhcy5udW1lcmljKCkgKQoKI3J0MSA8LSBycGFydChmb3JtdWxhID0gY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IGRhdGVfYXNudW1lcmljLCBkYXRhPXRlc3QpCiNpbnRlcnBvbGF0ZWQgPSBkYXRhLmZyYW1lKGRhdGVfYXNudW1lcmljPW1pbih0ZXN0JGRhdGVfYXNudW1lcmljKTptYXgodGVzdCRkYXRlX2FzbnVtZXJpYykgKQojaW50ZXJwb2xhdGVkJGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgPC0gIHByZWRpY3QocnQxLCBuZXdkYXRhPWludGVycG9sYXRlZCkKI2ludGVycG9sYXRlZCRkYXRlX2FzZGF0ZSA8LSBhcy5EYXRlKGludGVycG9sYXRlZCRkYXRlX2FzbnVtZXJpYykKCnAwYSA8LSB0ZXN0ICU+JQogICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICBnZ3RpdGxlKCJVU0EgUTMwIENvbmZpcm1lZCIpICMgKyBmYWNldF93cmFwKH5kYXRhc2V0KSAKCnAwYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMyApICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIgICkgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIlVTQSBRMzAgQ29uZmlybWVkIikgIyArIGZhY2V0X3dyYXAofmRhdGFzZXQpKyB5bGFiKCJEYWlseSBQZXJjZW50IENoYW5nZSBDb25maXJtZWQiKQoKI3AwYSAvIHAwYgoKCgojIyMjIwojQ2hpbmEgUTE0OAoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMTQ4IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKCnAxYSA8LSB0ZXN0ICU+JSAKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiQ2hpbmEgUTE0OCBDb25maXJtZWQiKQoKcDFiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiQ2hpbmEgUTE0OCBDb25maXJtZWQiKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKICAgCgojcDFhIC8gcDFiCgojSW5kaWEKIyJRNjY4IgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlE2NjgiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCgpwMmEgPC0gdGVzdCAlPiUKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSW5kaWEgUTY2OCBDb25maXJtZWQiKQoKcDJiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSW5kaWEgUTY2OCBDb25maXJtZWQiKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKIAogIAojcDJhIC8gcDJiCgoKCiNJdGFseQojIlEzOCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMzgiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCgpwNGEgPC0gdGVzdCAlPiUKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSXRhbHkgUTM4IENvbmZpcm1lZCIpCgpwNGIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJJdGFseSBRMzggQ29uZmlybWVkIikrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIENvbmZpcm1lZCIpCiAgIAogICAgCiNwNGEgLyBwNGIKCgoKI1NvdXRoIEtvcmVhCiMiUTg4NCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRODg0IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgoKcDVhIDwtIHRlc3QgJT4lCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIlNvdXRoIEtvcmVhIFE4ODQgIENvbmZpcm1lZCIpCgpwNWIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJTb3V0aCBLb3JlYSBRODg0IENvbmZpcm1lZCIpICsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKICAgCiAgICAKI3A1YSAvIHA1YgpgYGAKCgoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02ICx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CihwMGEgKyBwMWEgKyBwMmEgKSAvIChwMGIgKyBwMWIgKyBwMmIgKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NiAsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQooIHA0YSArIHA1YSkgLyAoIHA0YiArIHA1YikKYGBgCgpgYGB7cn0KCgp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTE0MzkiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCgpwMGEgPC0gdGVzdCAlPiUKICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiVGV4YXMgUTE0MzkgQ29uZmlybWVkIikKCnAwYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIlRleGFzIFExNDM5IENvbmZpcm1lZCIpICsgeWxpbSgwLDEwMCkrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIENvbmZpcm1lZCIpCgojQmV4YXIKIyJRMTY4NjEiCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMTY4NjEiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKcDFhIDwtIHRlc3QgJT4lCiAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIkJleGFyIENvdW50eSBRMTY4NjEgQ29uZmlybWVkIikKcDFiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiQmV4YXIgQ291bnR5IFExNjg2MSBDb25maXJtZWQiKSArIHlsaW0oMCwxMDApKyB5bGFiKCJEYWlseSBQZXJjZW50IENoYW5nZSBDb25maXJtZWQiKQoKI0NhbGlmb3JuaWEKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlE5OSIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQpwMmEgPC0gdGVzdCAlPiUKICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiQ2FsaWZvcm5pYSBROTkgQ29uZmlybWVkIikKcDJiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiQ2FsaWZvcm5pYSBROTkgQ29uZmlybWVkIikgKyB5bGltKDAsMTAwKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKCiNTYW4gRGllZ28gQ291bnR5IChRMTA4MTQzKQp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTEwODE0MyIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQpwM2EgPC0gdGVzdCAlPiUKICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiU2FuIERpZWdvIENvdW50eSAoUTEwODE0MykgQ29uZmlybWVkIikKcDNiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiU2FuIERpZWdvIENvdW50eSAoUTEwODE0MykgQ29uZmlybWVkIikgKyB5bGltKDAsMTAwKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKCiNGbG9yaWRhIChRODEyKQp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTgxMiIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsY29uZmlybWVkX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQpwNGEgPC0gdGVzdCAlPiUKICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiRmxvcmlkYSAoUTgxMikgQ29uZmlybWVkIikKcDRiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiRmxvcmlkYSAoUTgxMikgQ29uZmlybWVkIikgKyB5bGltKDAsMTAwKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgQ29uZmlybWVkIikKCgojU3QuIEx1Y2llIENvdW50eSAoUTQ5NDU2NCkKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlE0OTQ1NjQiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGNvbmZpcm1lZF9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKcDVhIDwtIHRlc3QgJT4lCiAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIlN0LiBMdWNpZSBDb3VudHkgKFE0OTQ1NjQpIENvbmZpcm1lZCIpCnA1YiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIlN0LiBMdWNpZSBDb3VudHkgKFE0OTQ1NjQpIENvbmZpcm1lZCIpICsgeWxpbSgwLDEwMCkrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIENvbmZpcm1lZCIpCgoKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTYgLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KI05vdCBjb3VudGluZyBzbG9wZXMgdGhhdCB3ZXJlIGludGVycG9sYXRlZCBvdXQgb2YgZG9tYWluIGZpeGVkIGNhbGlmb3JuaWEncyBwbG90CiggcDBhICsgcDFhICkgLyAoIHAwYiArIHAxYiApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02ICx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CiggcDJhICsgcDNhICkgLyAoIHAyYiArIHAzYiApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02ICx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CiggcDRhICsgcDVhKSAvICggcDRiICsgcDViKQpgYGAKCgojIyBQbG90IERlYXRoIEN1cnZlcyBmb3IgU2VsZWN0IExvY2F0aW9ucwoKU2hvdyBob3cgaW50ZXJwb2xhdGlvbiB3b3JrcyBvbiBkZWF0aHMKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxkZWF0aHNfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGZpbHRlcih3aWtpZGF0YV9pZD09IlEzMCIpICU+JSAKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAgJT4lCiAgICAgICAgbXV0YXRlKGRhdGVfYXNudW1lcmljID0gZGF0ZV9hc2RhdGUgJT4lIGFzLm51bWVyaWMoKSApCgpwMGEgPC0gdGVzdCAlPiUKICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgICAgZ2d0aXRsZSgiVVNBIFEzMCBEZWF0aHMiKSAjICsgZmFjZXRfd3JhcCh+ZGF0YXNldCkgCgpwMGIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMgKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siICApICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICBnZ3RpdGxlKCJVU0EgUTMwIERlYXRocyIpICsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgRGVhdGhzIikgIyArIGZhY2V0X3dyYXAofmRhdGFzZXQpCgojcDBhIC8gcDBiCgoKIyMjIyMKI0NoaW5hIFExNDgKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsZGVhdGhzX2xvZ19ncm91cF9udW1iZXIpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTE0OCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsZGVhdGhzX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCgpwMWEgPC0gdGVzdCAlPiUgCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIkNoaW5hIFExNDggRGVhdGhzIikKCnAxYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIkNoaW5hIFExNDggRGVhdGhzIikrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIERlYXRocyIpCiAgIAoKI3AxYSAvIHAxYgoKI0luZGlhCiMiUTY2OCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRNjY4IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxkZWF0aHNfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgoKcDJhIDwtIHRlc3QgJT4lCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIkluZGlhIFE2NjggRGVhdGhzIikKCnAyYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PWRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIkluZGlhIFE2NjggRGVhdGhzIikrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIERlYXRocyIpCiAKICAKI3AyYSAvIHAyYgoKI0JleGFyCiMiUTE2ODYxIgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCxkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSkgJT4lIGZpbHRlcih3aWtpZGF0YV9pZD09IlExNjg2MSIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsZGVhdGhzX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKCnAzYSA8LSB0ZXN0ICU+JQogICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICBnZ3RpdGxlKCJCZXhhciBDb3VudHkgUTE2ODYxIERlYXRocyIpCgpwM2IgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJCZXhhciBDb3VudHkgUTE2ODYxIERlYXRocyIpICsgeWxpbSgwLDEwMCkrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIERlYXRocyIpCiAgIAojcDNhIC8gcDNiCgoKCiNJdGFseQojIlEzOCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMzgiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLGRlYXRoc19sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIGRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPWRlYXRoc19sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCgpwNGEgPC0gdGVzdCAlPiUKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSXRhbHkgUTM4IERlYXRocyIpCgpwNGIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJJdGFseSBRMzggRGVhdGhzIikrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIERlYXRocyIpCiAgIAogICAgCiNwNGEgLyBwNGIKCgoKI1NvdXRoIEtvcmVhCiMiUTg4NCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRODg0IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCxkZWF0aHNfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCBkZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgoKcDVhIDwtIHRlc3QgJT4lCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIlNvdXRoIEtvcmVhIFE4ODQgIERlYXRocyIpCgpwNWIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT1kZWF0aHNfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9ZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJTb3V0aCBLb3JlYSBRODg0IERlYXRocyIpICsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgRGVhdGhzIikKICAgCiAgICAKI3A1YSAvIHA1YgpgYGAKCkkgbmVlZCB0byBmaXggdGhpcywgVVNBIGhhcyBhIGZyYWN0aW9uIG9mIGEgZGVhdGgKCk5vdGUgdGhlIGRpc2NvbnRpbnVpdHkgaW4gQ2hpbiB3aGVuIHRoZXkgYWRkZWQgdGhvc2UgMWsgZGVhdGhzIHRvIHRoZSB0b3RhbAoKSW5kaWEgZGVhdGhzIGlzIGJyb2tlbiwgd2Ugc2hvdWxkbid0IGJlIGludGVycG9sYXRpbmcgYSByYXRlIGJlZm9yZSB3ZSB0aGluayB0aGUgbnVtYmVyIGlzIGdyZWF0ZXIgdGhhbiAwCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTYgLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KKHAwYSArIHAxYSArIHAyYSApIC8gKHAwYiArIHAxYiArIHAyYiApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02ICx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CihwM2EgKyBwNGEgKyBwNWEpIC8gKHAzYiArIHA0YiArIHA1YikKYGBgCgoKCiMjIFBsb3QgVGVzdGluZyBDdXJ2ZXMgZm9yIFNlbGVjdCBMb2NhdGlvbnMKClNob3cgaG93IGludGVycG9sYXRpb24gd29ya3Mgb24gdGVzdGVkCgpVUyBpcyBhbiBleGFtcGxlIHdoZXJlIHdlIGludGVycG9sYXRlZCBwYXN0IG91ciBhdmFpbGFibGUgZGF0YS4gU2hvdWxkbid0IGRvIHRoYXQgZWl0aGVyIQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9Cgp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTMwIikgJT4lIAogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICAlPiUKICAgICAgICBtdXRhdGUoZGF0ZV9hc251bWVyaWMgPSBkYXRlX2FzZGF0ZSAlPiUgYXMubnVtZXJpYygpICkKCnAwYSA8LSB0ZXN0ICU+JQogICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgIGdndGl0bGUoIlVTQSBRMzAgVGVzdGVkIikgICMrIGZhY2V0X3dyYXAofmRhdGFzZXQpIAoKcDBiIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMyApICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siICApICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgIGdndGl0bGUoIlVTQSBRMzAgdGVzdGVkX3Blb3BsZSIpICsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgdGVzdGVkX3Blb3BsZSIpICMgKyBmYWNldF93cmFwKH5kYXRhc2V0KQoKI3AwYSAvIHAwYgoKCiMjIyMjCiNDaGluYSBRMTQ4Cgp0ZXN0IDwtIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LHdpa2lkYXRhX2lkLHRlc3RlZF9wZW9wbGVfbG9nX2dyb3VwX251bWJlcikpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMTQ4IikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCx0ZXN0ZWRfcGVvcGxlX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCgpwMWEgPC0gdGVzdCAlPiUgCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiQ2hpbmEgUTE0OCB0ZXN0ZWRfcGVvcGxlIikKCnAxYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJDaGluYSBRMTQ4IHRlc3RlZF9wZW9wbGUiKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgdGVzdGVkX3Blb3BsZSIpCiAgIAoKI3AxYSAvIHAxYgoKI0luZGlhCiMiUTY2OCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTY2OCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKCnAyYSA8LSB0ZXN0ICU+JQpnZ3Bsb3QoKSArIAogICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIkluZGlhIFE2NjggdGVzdGVkX3Blb3BsZSIpCgpwMmIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSW5kaWEgUTY2OCB0ZXN0ZWRfcGVvcGxlIikrIHlsYWIoIkRhaWx5IFBlcmNlbnQgQ2hhbmdlIHRlc3RlZF9wZW9wbGUiKQogCiAgCiNwMmEgLyBwMmIKCiNCZXhhcgojIlExNjg2MSIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTE2ODYxIikgJT4lIAogICAgICAgIG11dGF0ZShncm91cD1wYXN0ZShkYXRhc2V0LCB3aWtpZGF0YV9pZCx0ZXN0ZWRfcGVvcGxlX2xvZ19ncm91cF9udW1iZXIpKSAlPiUKICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAjJT4lCiAgICAgICAgI211dGF0ZSggdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgPSBicmVha3BvaW50cyhmb3JtdWxhPXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlIH4gMSwgZGF0YT0uICkgJT4lIGZpdHRlZC52YWx1ZXMoKSApCgoKcDNhIDwtIHRlc3QgJT4lCiAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgZ2d0aXRsZSgiQmV4YXIgQ291bnR5IFExNjg2MSB0ZXN0ZWRfcGVvcGxlIikKCnAzYiA8LSB0ZXN0ICU+JQogICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCApLCBhbHBoYT0xLCBjb2xvcj0iYmxhY2siKSArCiAgICAgICAgICNnZW9tX3Ntb290aCggYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlKSwgYWxwaGE9LjMsIHNwYW49LjA1KSArICMsIHNwYW49LjA1CiAgICAgICAgICNnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAgICAgICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJCZXhhciBDb3VudHkgUTE2ODYxIHRlc3RlZF9wZW9wbGUiKSArIHlsaW0oMCwxMDApKyB5bGFiKCJEYWlseSBQZXJjZW50IENoYW5nZSB0ZXN0ZWRfcGVvcGxlIikKICAgCiNwM2EgLyBwM2IKCgoKI0l0YWx5CiMiUTM4IgoKdGVzdCA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCx3aWtpZGF0YV9pZCx0ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSkpICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMzgiKSAlPiUgCiAgICAgICAgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsIHdpa2lkYXRhX2lkLHRlc3RlZF9wZW9wbGVfbG9nX2dyb3VwX251bWJlcikpICU+JQogICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICMlPiUKICAgICAgICAjbXV0YXRlKCB0ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSA9IGJyZWFrcG9pbnRzKGZvcm11bGE9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UgfiAxLCBkYXRhPS4gKSAlPiUgZml0dGVkLnZhbHVlcygpICkKCgpwNGEgPC0gdGVzdCAlPiUKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludCggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1kYXRhc2V0LCBncm91cD1ncm91cCkpICsgIwogICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJJdGFseSBRMzggdGVzdGVkX3Blb3BsZSIpCgpwNGIgPC0gdGVzdCAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICAgIGdlb21fcG9pbnQoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgICAgICAgIGdlb21fbGluZShhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQgKSwgYWxwaGE9MSwgY29sb3I9ImJsYWNrIikgKwogICAgICAgICAjZ2VvbV9zbW9vdGgoIGFlcyh4PWRhdGVfYXNkYXRlICwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSksIGFscGhhPS4zLCBzcGFuPS4wNSkgKyAjLCBzcGFuPS4wNQogICAgICAgICAjZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXApKSArICMKICAgICAgICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgICAgICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiSXRhbHkgUTM4IHRlc3RlZF9wZW9wbGUiKSsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgdGVzdGVkX3Blb3BsZSIpCiAgIAogICAgCiNwNGEgLyBwNGIKCgoKI1NvdXRoIEtvcmVhCiMiUTg4NCIKCnRlc3QgPC0gbGhzX2xvbmdfY2xlYW5faW1wdXRlZCAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKGRhdGFzZXQsd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTg4NCIpICU+JSAKICAgICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUoZGF0YXNldCwgd2lraWRhdGFfaWQsdGVzdGVkX3Blb3BsZV9sb2dfZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgIyU+JQogICAgICAgICNtdXRhdGUoIHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlID0gYnJlYWtwb2ludHMoZm9ybXVsYT10ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKQoKCnA1YSA8LSB0ZXN0ICU+JQpnZ3Bsb3QoKSArIAogICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT10ZXN0ZWRfcGVvcGxlX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS4zKSArCiAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIlNvdXRoIEtvcmVhIFE4ODQgIHRlc3RlZF9wZW9wbGUiKQoKcDViIDwtIHRlc3QgJT4lCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICBnZW9tX3BvaW50KCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UsIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICAgICAgICBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUgLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0ICksIGFscGhhPTEsIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgI2dlb21fc21vb3RoKCBhZXMoeD1kYXRlX2FzZGF0ZSAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2UpLCBhbHBoYT0uMywgc3Bhbj0uMDUpICsgIywgc3Bhbj0uMDUKICAgICAgICAgI2dlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwKSkgKyAjCiAgICAgICAgICNnZW9tX2xpbmUoZGF0YT10ZW1wX2RmMiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXRfbWVhbiksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICAgICAgICAgdGhlbWVfYncoKSArCiAgIGdndGl0bGUoIlNvdXRoIEtvcmVhIFE4ODQgdGVzdGVkX3Blb3BsZSIpICsgeWxhYigiRGFpbHkgUGVyY2VudCBDaGFuZ2UgdGVzdGVkX3Blb3BsZSIpCiAgIAogICAgCiNwNWEgLyBwNWIKYGBgCgoKTm90ZSB0aGF0IENoaW5hIGNvdW50cyBvZiB0ZXN0aW5nIGFyZSBhbG1vc3QgbmV2ZXIgZ2l2ZW4gYXQgdGhlIG5hdGlvbmFsIGxldmVsLiBXZSBoYXZlIHNvbWUgYnJva2VuIGRvd24gYnkgc3BlY2lmaWMgcHJvdmluY2VzIGJ1dCB0YWJsZXMgdXN1YWxseSBkb24ndCBoYXZlIGEgIkNoaW5hIiByb3cuCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTYgLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KKHAwYSArIHAxYSArIHAyYSApIC8gKHAwYiArIHAxYiArIHAyYiApCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02ICx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CihwM2EgKyBwNGEgKyBwNWEpIC8gKHAzYiArIHA0YiArIHA1YikKYGBgCgoKIyBBbGlnbmluZyBDdXJ2ZXMgYnkgVGFrZW9mZgoKYGBge3IsIGVjaG89RkFMU0Usd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KCmxpYnJhcnkoZGF0YS50YWJsZSkKZ2VvbmFtZXMgPC0gZnJlYWQoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2FsbENvdW50cmllcy50eHQiLCBzZXA9Ilx0IikgJT4lIG11dGF0ZV9pZihpcy5udW1lcmljLGFzLmNoYXJhY3RlcikgJT4lIG11dGF0ZV9pZihpcy5mYWN0b3IsYXMuY2hhcmFjdGVyKQpkaW0oZ2VvbmFtZXMpICMxMiwwMDYsNDI2CgpnZW9uYW1lc19zbWFsbCA8LSBnZW9uYW1lcyAlPiUgZHBseXI6OnNlbGVjdChnZW9uYW1laWQ9VjEsIG5hbWVfdGV4dD1WMikgJT4lIGlubmVyX2pvaW4oIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIGRwbHlyOjpzZWxlY3QoZ2VvbmFtZWlkKSAlPiUgZGlzdGluY3QoKSApCmRpbShnZW9uYW1lc19zbWFsbCkKCmRmX3Nsb3BlcyA8LSBsaHNfbG9uZ19jbGVhbl9pbXB1dGVkICU+JSAKICAgICAgICAgICAgIGdyb3VwX2J5KGdpZF9nZW9uYW1laWRfd2lraWRhdGFfaWQsIGdpZCwgZ2VvbmFtZWlkLCB3aWtpZGF0YV9pZCwgZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICAgIHN1bW1hcmlzZSgKICAgICAgICAgICAgICAgICAgICBjb25maXJtZWQ9bWVkaWFuKGNvbmZpcm1lZCwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgZGVhdGhzPW1lZGlhbihkZWF0aHMsIG5hLnJtPVQpLAogICAgICAgICAgICAgICAgICAgIHRlc3RlZF9wZW9wbGU9bWVkaWFuKHRlc3RlZF9wZW9wbGUsIG5hLnJtPVQpLAogICAgICAgICAgICAgICAgICAgIHRlc3RlZF9zYW1wbGVzPW1lZGlhbih0ZXN0ZWRfc2FtcGxlcywgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgY29uZmlybWVkX2xvZ195X2hhdD1tZWRpYW4oY29uZmlybWVkX2xvZ195X2hhdCwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgZGVhdGhzX2xvZ195X2hhdD1tZWRpYW4oZGVhdGhzX2xvZ195X2hhdCwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQ9bWVkaWFuKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBuYS5ybT1UKSwKCiAgICAgICAgICAgICAgICAgICAgY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZT1tZWRpYW4oY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZT1tZWRpYW4oZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZSwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2U9bWVkaWFuKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlLCBuYS5ybT1UKSwKCiAgICAgICAgICAgICAgICAgICAgY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdD1tZWRpYW4oY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdD1tZWRpYW4oZGVhdGhzX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgdGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQ9bWVkaWFuKHRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0LCBuYS5ybT1UKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICN0ZXN0ZWRfc2FtcGxlc19sb2dfeV9oYXQ9bWVkaWFuKHRlc3RlZF9zYW1wbGVzX2xvZ195X2hhdCwgbmEucm09VCksICNoYXZlbid0IHdyaXR0ZW4gdGhlIGludGVycCBmb3IgdGhpcyB5ZXQKICAgICAgICAgICAgICAgICAgICApICU+JQogICAgICAgICAgICAgI3VuZ3JvdXAoKSAlPiUKICAgICAgICAgICAgIGxlZnRfam9pbihnZW9uYW1lc19zbWFsbCkgJT4lCiAgICAgICAgICAgICBncm91cF9ieShnaWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkKSAlPiUgCiAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgICAgICBtdXRhdGUodCA9IHJvd19udW1iZXIoKSkgJT4lCiAgICAgICAgICAgICBtdXRhdGUoY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdF9mZD10c2liYmxlOjpkaWZmZXJlbmNlKGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQpKSAlPiUKICAKICAgICAgICAgICAgICNTbyB0aGVyZSBhcmUgb25lcyB0aGF0IHN0YXJ0IGxvdyBhbmQgYnVpbGQgdXAKICAgICAgICAgICAgIG11dGF0ZSh0X2FsbGlnbmVkX21heGZkID0gIGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXRfZmQ9PW1heChjb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0X2ZkLG5hLnJtPVQpICkgJT4lIAogICAgICAgICAgICAgI2J1dCB0aGVyZSBhcmUgb3RoZXIgb25lcyB0aGF0IGdvIGZyb20gemVybyB0byBoaWdoIGFuZCB0aG9zZSBhcmVuJ3QgZ2V0dGluZyBjYXVnaHQgYnkgdGhlIHRvcCBhYm92ZQogICAgICAgICAgICAgbXV0YXRlKHRfYWxsaWduZWRfbWF4X2F0XzAgPSAgY29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdD09bWF4KGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQsbmEucm09VCkgJiB0PT0xICkgJT4lIAoKICAgICAgICAgICAgIG11dGF0ZSh0X2FsbGlnbmVkID0gaWZlbHNlKHRfYWxsaWduZWRfbWF4X2F0XzAgfCAodF9hbGxpZ25lZF9tYXhmZCAmIG1heCh0X2FsbGlnbmVkX21heF9hdF8wLCBuYS5ybT1UKT09RikgLCB0LCBOQSkgKSAlPiUgCiAgICAgICAgICAgICBtdXRhdGUodF9hbGxpZ25lZCA9IG1heCh0X2FsbGlnbmVkLCBuYS5ybT1UKSApICU+JQogICAgICAgICAgICAgbXV0YXRlKHRfYWxsaWduZWQgPSB0LW1heCh0X2FsbGlnbmVkLCBuYS5ybT1UKSApICU+JQoKICAgICAgICAgICAgIG11dGF0ZSh0X2FsbGlnbmVkX2ZpcnN0Y29uZmlybWVkID0gaWZlbHNlKGNvbmZpcm1lZD09bWluKGNvbmZpcm1lZCwgbmEucm09VCkgLCB0LCBOQSkgKSAlPiUgCiAgICAgICAgICAgICBtdXRhdGUodF9hbGxpZ25lZF9maXJzdGNvbmZpcm1lZCA9IG1heCh0X2FsbGlnbmVkX2ZpcnN0Y29uZmlybWVkLCBuYS5ybT1UKSApICU+JQogICAgICAgICAgICAgbXV0YXRlKHRfYWxsaWduZWRfZmlyc3Rjb25maXJtZWQgPSB0LW1heCh0X2FsbGlnbmVkX2ZpcnN0Y29uZmlybWVkLCBuYS5ybT1UKSApICU+JQoKICAgICAgICAgICAgICN0aGlzIHRocm93cyBhIGJ1bmNoIG9mIGluZmluaXRlIG1pc3NpbmcgYmVjYXVzZSBvZiBjb3VudHJpZXMgdGhhdCBoYXZlbid0IHlldCBoaXQgMTAwCiAgICAgICAgICAgICAjbXV0YXRlKHRfYWxsaWduZWRfMTAwY29uZmlybWVkXzEwMCA9IGlmZWxzZShjb25maXJtZWQ+PTEwMCAgLCB0LCBOQSkgKSAlPiUgCiAgICAgICAgICAgICAjbXV0YXRlKHRfYWxsaWduZWRfMTAwY29uZmlybWVkXzEwMCA9IGlmZWxzZSh0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZF8xMDA9PW1pbih0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZF8xMDAsIG5hLnJtPVQpICwgdCwgTkEpICkgJT4lIAogICAgICAgICAgICAgI211dGF0ZSh0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZCA9IHQtbWF4KHRfYWxsaWduZWRfMTAwY29uZmlybWVkXzEwMCwgbmEucm09VCkgKSAlPiUKICAgICAgICAgICAgICNkcGx5cjo6c2VsZWN0KC10X2FsbGlnbmVkXzEwMGNvbmZpcm1lZF8xMDApICU+JQogICAgICAgICAgICAgdW5ncm91cCgpCmBgYAoKYGBge3IsIGV2YWw9Rn0KCmxpYnJhcnkoaW5mb3RoZW8pCiNPbmNlIHdlIHJlbW92ZWQgdGhlIG5vIHZhcmlhbmNlIHBsYWNlcyBteSBhbGlnbm1lbnQgaGFzIG1vcmUgbXV0dWFsIGluZm9ybWF0aW9uIHRoYW4gZWl0aGVyIGZpcnN0IGNvbmZpcm1lZCBvciAxMDAgY29uZmlybWVkCm11dGluZm9ybWF0aW9uKFg9ZGZfc2xvcGVzICU+JSBkcGx5cjo6c2VsZWN0KHQsdF9hbGxpZ25lZCx0X2FsbGlnbmVkX2ZpcnN0Y29uZmlybWVkLGNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQpICU+JSBkaXNjcmV0aXplKCksIG1ldGhvZD0iZW1wIikgI3dlIG91dHBlcmZvcm1lZCB0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZCBidXQgaXQgd2Fzbid0IGF2YWlsIGZvciBtb3N0CgojZGZfc2xvcGVzICU+JSBmaWx0ZXIoYWJzKHRfYWxsaWduZWQpPDIwLGFicyh0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZF8xMDApPDIwKSAlPiUgamFuaXRvcjo6dGFieWwodF9hbGxpZ25lZCwgdF9hbGxpZ25lZF8xMDBjb25maXJtZWRfMTAwKQojaGlzdChkZl9zbG9wZXMkdF9hbGxpZ25lZCAtIGRmX3Nsb3BlcyR0X2FsbGlnbmVkXzEwMGNvbmZpcm1lZF8xMDAsIGJyZWFrcz01MCkKICAKYGBgCgpQbG90IG9mIGN1cnZlcyByYXcgYW5kIHRoZW4gY3VydmVzIGFsbGlnbmVkIGJ5IHRha2VvZmYgc3RhcnQKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTIsIGVjaG89RkFMU0Usd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KCiNkZl9zbG9wZXMgJT4lIG11dGF0ZShncm91cD1wYXN0ZSh3aWtpZGF0YV9pZCkpICU+JQojICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAojICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PXRfYWxsaWduZWQgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQsIGdyb3VwPXdpa2lkYXRhX2lkKSwgYWxwaGE9LjA1LCBjb2xvcj0iYmx1ZSIpICsKIyAgICAgICAgICAgICAgdGhlbWVfYncoKSArCiMgICAgICAgICAgICAgIGdndGl0bGUoIkludGVycG9sYXRlZCBsb2cgY291bnQgYnkgQWxsaWduZWQgVCIpICsgeWxpbSgwLDEwMCkKCgpwX3RfYWxsaWduZWRfZmlyc3Rjb25maXJtZWQgPC0gIGRmX3Nsb3BlcyAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKHdpa2lkYXRhX2lkKSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9dF9hbGxpZ25lZF9maXJzdGNvbmZpcm1lZCAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCwgZ3JvdXA9Z3JvdXAsIGNvbG9yPXdpa2lkYXRhX2lkKSwgYWxwaGE9MSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJJbnRlcnBvbGF0ZWQgbG9nIGNvdW50IGJ5IFQiKSArIHlsaW0oMCwxMDApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdnaGlnaGxpZ2h0KHdpa2lkYXRhX2lkICVpbiUgYygnUTMwJywnUTE0MzknLCdRNjY4JywnUTg4NCcsJ1ExNjg2MScsJ1ExNTknLCdRMzgnKSwgdW5oaWdobGlnaHRlZF9wYXJhbXM9bGlzdChhbHBoYT0uMSkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9zbW9vdGgoIGFlcyh4PXRfYWxsaWduZWRfZmlyc3Rjb25maXJtZWQgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQpLCBzcGFuID0gMC4wNSkgICsgeGxpbSgtNTAsMTAwKQoKI3BfdF9hbGxpZ25lZF9maXJzdGNvbmZpcm1lZAoKCnBfdF9hbGxpZ25lZCA8LSBkZl9zbG9wZXMgJT4lIG11dGF0ZShncm91cD1wYXN0ZSh3aWtpZGF0YV9pZCkpICU+JSAKICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD10X2FsbGlnbmVkICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0LCBncm91cD1ncm91cCwgY29sb3I9d2lraWRhdGFfaWQpLCBhbHBoYT0xKSArCiAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICBnZ3RpdGxlKCJJbnRlcnBvbGF0ZWQgbG9nIGNvdW50IGJ5IEFsbGlnbmVkIFQiKSArIHlsaW0oMCwxMDApICsKICAgICAgICAgICAgICAgZ2doaWdobGlnaHQod2lraWRhdGFfaWQgJWluJSBjKCdRMzAnLCdRMTQzOScsJ1E2NjgnLCdRODg0JywnUTE2ODYxJywnUTE1OScsJ1EzOCcpLCB1bmhpZ2hsaWdodGVkX3BhcmFtcz1saXN0KGFscGhhPS4xKSkgKwogICAgICAgICAgICAgICBnZW9tX3Ntb290aCggYWVzKHg9dF9hbGxpZ25lZCAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCksIHNwYW4gPSAwLjA1KSArIHhsaW0oLTUwLDEwMCkKCiNwX3RfYWxsaWduZWQKI2RmX3Nsb3BlcyAlPiUgbXV0YXRlKGdyb3VwPXBhc3RlKHdpa2lkYXRhX2lkKSkgJT4lIAojZ2dwbG90KCkgKyAKIyAgIGdlb21fbGluZSggYWVzKHg9dF9hbGxpZ25lZCAsIHk9Y29uZmlybWVkX2xvZ195X2hhdF9wZXJjZW50X2NoYW5nZV95X2hhdCwgZ3JvdXA9Z3JvdXAsIGNvbG9yPXdpa2lkYXRhX2lkKSwgYWxwaGE9MSkgKwojICAgdGhlbWVfYncoKSArCiMgICBnZ3RpdGxlKCJJbnRlcnBvbGF0ZWQgbG9nIGNvdW50IGJ5IEFsbGlnbmVkIFQiKSArIHlsaW0oMCwxMDApICArIHhsaW0oMCwxMDApICsKIyAgIGdnaGlnaGxpZ2h0KHdpa2lkYXRhX2lkICVpbiUgYygnUTMwJywnUTE0MzknLCdRNjY4JywnUTg4NCcsJ1ExNjg2MScsJ1ExNTknLCdRMzgnKSwgdW5oaWdobGlnaHRlZF9wYXJhbXM9bGlzdChhbHBoYT0uMSkpICsKIyAgIGdlb21fc21vb3RoKCBhZXMoeD10X2FsbGlnbmVkICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0KSwgc3BhbiA9IDAuMDUpIAoKCgpgYGAKClRoZSBpZGVhIGhlcmUgaXMgdGhhdCBjb21wbGV0ZWx5IHVuY29uc3RyYWluZWQsIENPVklELTE5IGdyb3d0aCBzaG91bGQgZm9sbG93IGEgbG9naXN0aWMgY3VydmUsIGZsYXQsIHVwc3dpbmcsIGNvbnN0YW50IGdyb3d0aCwgZG93bnN3aW5nLCBhbmQgZmxhdCBhZ2Fpbi4gVGhlIGFzc3VtcHRpb24gb2Ygbm8gdW5jb25zdHJhaW5lZCBncm93dGggbm8gbG9uZ2VyIGhvbGRzIGJlY2F1c2UgdGhlIHdvcmxkIGlzIHJlYWN0aW5nLCBidXQgdGhlcmUncyBzdGlsbCBhIHByZXR0eSB1bmlmb3JtbHkgY2hhcmFjdGVyaXN0aWMgdXBzd2luZyBhY3Jvc3MgZ2VvZ3JhcGhpYyB1bml0cy4gV2UgbG9vayBmb3IgdGhpcyBzaWduYWwgb2YgdGhlIGxhcmdlc3QgZmlyc3QgZGlmZmVyZW5jZSBpbiB0aGUgZGFpbHkgcGVyY2VudCBjaGFuZ2UsIGNhbGwgdGhhdCB0aGUgdGFrZW9mZiBkYXRlLCBhbmQgdGhlbiBhbGxpZ24gYWxsIHRoZSB0aW1lIHNlcmllcyB3aXRoIHRoYXQgZGF0ZSBhcyAwLgoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CnBfdF9hbGxpZ25lZF9maXJzdGNvbmZpcm1lZCAgLyBwX3RfYWxsaWduZWQgCmBgYAoKCgoKIyMgUGxvdHMgYnkgQ291bnRyaWVzCgpXZSBoYXZlIHRvIGFkZCBnZW9jb2RlcyB0byB0aGUgbWFwIHBsYWNlbWVudHMKCmBgYHtyfQoKCmFkbWluMCA8LSByZWFkUkRTKCIvbWVkaWEvc2t5bmV0Mi85MDU4ODRmMC03NTQ2LTQyNzMtOTA2MS0xMmE3OTA4MzBiZWIvcndkX2dpdGh1Yl9wcml2YXRlL05FU1Njb3ZpZDE5L2RhdGFfaW4vYWRtaW4wLlJkcyIpCmFkbWluMSA8LSByZWFkUkRTKCIvbWVkaWEvc2t5bmV0Mi85MDU4ODRmMC03NTQ2LTQyNzMtOTA2MS0xMmE3OTA4MzBiZWIvcndkX2dpdGh1Yl9wcml2YXRlL05FU1Njb3ZpZDE5L2RhdGFfaW4vYWRtaW4xLlJkcyIpCmFkbWluMiA8LSByZWFkUkRTKCIvbWVkaWEvc2t5bmV0Mi85MDU4ODRmMC03NTQ2LTQyNzMtOTA2MS0xMmE3OTA4MzBiZWIvcndkX2dpdGh1Yl9wcml2YXRlL05FU1Njb3ZpZDE5L2RhdGFfaW4vYWRtaW4yLlJkcyIpCgpyZXhfY2xlYW4gPC0gZnVuY3Rpb24oeCl7IHggJT4lIHN0cmluZ2k6OnN0cmlfdHJhbnNfZ2VuZXJhbCgibGF0aW4tYXNjaWkiKSAlPiUgc3RyaW5naTo6c3RyaV9yZXBsYWNlX2FsbChyZWdleD0iW15BLVphLXowLTldIiwiIikgJT4lIHRvbG93ZXIoKSB9ICNzbyBpbmRpdmlkdWFsbHksIGVhY2ggc3RyaW5nIHNob3VsZCBiZSBkZXZvaWQgb2Ygc3BhY2VzLG5vbmNoYXJhY3RlcnMsIGFuZCBub25sYXRpbgoKcmV4X2FkbWluX2Z1bmN0aW9uIDwtIGZ1bmN0aW9uKHgpIHsKICB4ICU+JSAKICBsZWZ0X2pvaW4oYWRtaW4wICkgJT4lCiAgbGVmdF9qb2luKGFkbWluMSApICAlPiUKICBsZWZ0X2pvaW4oYWRtaW4yICkgJT4lCiAgbXV0YXRlKGdpZD1pZmVsc2UoIWlzLm5hKGFkbWluMl9uYW1lX2NsZWFuKSAmIGFkbWluMl9uYW1lX2NsZWFuIT0nJyxnaWQyLGlmZWxzZSghaXMubmEoYWRtaW4xX25hbWVfY2xlYW4pICYgYWRtaW4xX25hbWVfY2xlYW4hPScnLCBnaWQxLCBnaWQwKSkpICU+JQogIG11dGF0ZSh3aWtpZGF0YV9pZD1pZmVsc2UoIWlzLm5hKGFkbWluMl9uYW1lX2NsZWFuKSAmIGFkbWluMl9uYW1lX2NsZWFuIT0nJyx3aWtpZGF0YV9pZDIsaWZlbHNlKCFpcy5uYShhZG1pbjFfbmFtZV9jbGVhbikgJiBhZG1pbjFfbmFtZV9jbGVhbiE9JycsIHdpa2lkYXRhX2lkMSwgd2lraWRhdGFfaWQwKSkpICU+JQogIG11dGF0ZShnZW9uYW1laWQ9aWZlbHNlKCFpcy5uYShhZG1pbjJfbmFtZV9jbGVhbikgJiBhZG1pbjJfbmFtZV9jbGVhbiE9JycsZ2VvbmFtZWlkMixpZmVsc2UoIWlzLm5hKGFkbWluMV9uYW1lX2NsZWFuKSAmIGFkbWluMV9uYW1lX2NsZWFuIT0nJywgZ2VvbmFtZWlkMSwgZ2VvbmFtZWlkMCkpKSAlPiUKICBtdXRhdGUoYWRtaW5fbGV2ZWw9aWZlbHNlKCFpcy5uYShhZG1pbjJfbmFtZV9jbGVhbikgJiBhZG1pbjJfbmFtZV9jbGVhbiE9JycsMixpZmVsc2UoIWlzLm5hKGFkbWluMV9uYW1lX2NsZWFuKSAmIGFkbWluMV9uYW1lX2NsZWFuIT0nJywgMSwgMCkpKQp9CgpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KaW5zdGFsbC5wYWNrYWdlcygiZ2VvZmFjZXQiKQojIG9yIGZyb20gZ2l0aHViOgojIGRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiaGFmZW4vZ2VvZmFjZXQiKQpsaWJyYXJ5KGdlb2ZhY2V0KQpoZWFkKHVzX3N0YXRlX2dyaWQyKQoKYGBgCgojIyMgQ29uZmlybWVkLCBEZWF0aHMsIFRlc3RzCgpCeSBjb3VudHJ5IAoKYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQoKZ2FkbTM2ID0gc3RfcmVhZCgiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTZ2FkbS9kYXRhX2luL2dhZG0zNl9ncGtnL2dhZG0zNi5ncGtnIikKZ2FkbTM2X2RmIDwtIGdhZG0zNiAlPiUgYXMuZGF0YS5mcmFtZSgpCmNvdW50cmllcyA8LSBnYWRtMzZfZGYgJT4lIGRwbHlyOjpzZWxlY3QoZ2lkPUdJRF8wLCBuYW1lPU5BTUVfMCApICU+JSBkaXN0aW5jdCgpCgp0ZW1wMSA8LSBkZl9zbG9wZXMgJT4lCiAgICAgICAgICBmaWx0ZXIoIWdpZCAlPiUgc3RyX2RldGVjdCgiXyIpICkgJT4lCiAgICAgICAgICBsZWZ0X2pvaW4oY291bnRyaWVzICU+JSBkcGx5cjo6c2VsZWN0KGdpZCwgbmFtZV90ZXh0PW5hbWUpICkgJT4lIAogICAgICAgICAgI2xlZnRfam9pbihnZW9uYW1lc19zbWFsbCAgKSAlPiUgCiAgCiAgICAgICAgICBtdXRhdGUobmFtZV90ZXh0PW5hbWVfdGV4dCAlPiUgYXMuZmFjdG9yKCkpICU+JQogICAgICAgICAgbGVmdF9qb2luKHdvcmxkX2NvdW50cmllc19ncmlkMSwgYnk9YygnZ2lkJz0nY29kZV9hbHBoYTMnKSkgJT4lCiAgICAgICAgICBmaWx0ZXIoIWlzLm5hKG5hbWUpKQp0ZW1wMiA8LSB0ZW1wMSAlPiUgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lIGZpbHRlcighZHVwbGljYXRlZChnaWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkKSkgJT4lIG11dGF0ZShuYW1lX3RleHQ9bmFtZSAlPiUgYXMuZmFjdG9yKCkpCgpoZWFkKHdvcmxkX2NvdW50cmllc19ncmlkMSkKd29ybGRfY291bnRyaWVzX2dyaWQxX3JleCA8LSB3b3JsZF9jb3VudHJpZXNfZ3JpZDEgJT4lIGZpbHRlcihuYW1lICVpbiUgdGVtcDIkbmFtZSkKZGltKHdvcmxkX2NvdW50cmllc19ncmlkMV9yZXgpCmdyaWRfcHJldmlldyh3b3JsZF9jb3VudHJpZXNfZ3JpZDFfcmV4KQoKcF9jb25maXJtZWRfZGVhdGhzX3Rlc3RfYnlfY291bnRyeSA8LSB0ZW1wMSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQpLCBjb2xvcj0icmVkIikgKyAjICN0IGFsaWduZWQgaXMgYnJva2VuIGZvciB0aGUgVS5TLiBhbmQgc29tZSBjb3VudHJpZXMsIGFsbCBpbmZpbml0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWRlYXRoc19sb2dfeV9oYXQpLCBjb2xvcj0iYmxhY2siKSArICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0KSwgY29sb3I9ImJsdWUiKSArICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJHbG9iYWwgQ292aWQtMTk6IExvZyBUZXN0ZWQgKGJsdWUpIENvbmZpcm1lZCAocmVkKSwgRGVhdGggKGJsYWNrKSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlcyggY29sb3IgPSBGQUxTRSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZXRfd3JhcCh+bmFtZV90ZXh0ICAgKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fdGV4dChkYXRhPXRlbXAyLHg9MTgyODIrMjAseT0xNCxhZXMobGFiZWw9bmFtZV90ZXh0KSwgc2l6ZT0yLjUpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvdW50cyAobG9nKSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIoIkRheXMgYmVmb3JlL1NpbmNlIFRha2VvZmYgaW4gQ29uZmlybWVkIE51bWJlcnMiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9nZW8ofm5hbWUsIGdyaWQgPXdvcmxkX2NvdW50cmllc19ncmlkMV9yZXgpIApgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTJ9CnBfY29uZmlybWVkX2RlYXRoc190ZXN0X2J5X2NvdW50cnkKYGBgCgpVLlMuIGJ5IFN0YXRlCgpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9Cgp0ZW1wMSA8LSBkZl9zbG9wZXMgJT4lCiAgICAgICAgICBmaWx0ZXIoZ2lkICU+JSBzdHJfZGV0ZWN0KCJVU0FcXC5bMC05XXsxLDJ9XzEkIikgKSAlPiUKICAgICAgICAgIGxlZnRfam9pbihnZW9uYW1lc19zbWFsbCAgKSAlPiUgbXV0YXRlKG5hbWVfdGV4dD0gbmFtZV90ZXh0ICU+JSBhcy5mYWN0b3IoKSkgJT4lCiAgICAgICAgICBsZWZ0X2pvaW4odXNfc3RhdGVfZ3JpZDIsIGJ5PWMoJ25hbWVfdGV4dCc9J25hbWUnKSkgJT4lIAogICAgICAgICAgZmlsdGVyKCFpcy5uYShuYW1lX3RleHQpKQp0ZW1wMiA8LSB0ZW1wMSAlPiUgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lIGZpbHRlcighZHVwbGljYXRlZChnaWRfZ2VvbmFtZWlkX3dpa2lkYXRhX2lkKSkgJT4lIG11dGF0ZShuYW1lX3RleHQ9bmFtZV90ZXh0ICU+JSBhcy5mYWN0b3IoKSkKCiN0X2FsbGlnbmVkCnBfY29uZmlybWVkX2RlYXRoc190ZXN0X2J5X3N0YXRlX3VzIDwtIHRlbXAxICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNmaWx0ZXIoZ2lkPT0iVVNBIikgJT4lICNqdXN0IGEgdGVzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCksIGNvbG9yPSJyZWQiKSArICMgI3QgYWxpZ25lZCBpcyBicm9rZW4gZm9yIHRoZSBVLlMuIGFuZCBzb21lIGNvdW50cmllcywgYWxsIGluZmluaXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1kZWF0aHNfbG9nX3lfaGF0KSwgY29sb3I9ImJsYWNrIikgKyAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0KSwgY29sb3I9ImJsdWUiKSArICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZSgiQ292aWQtMTkgQnkgVS5TLiBTdGF0ZTogTG9nIFRlc3RlZCAoYmx1ZSkgQ29uZmlybWVkIChyZWQpLCBEZWF0aCAoYmxhY2spIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV90ZXh0KGRhdGE9dGVtcDIseD0xODI4MisyMCx5PTEyLGFlcyhsYWJlbD1uYW1lX3RleHQpLCBzaXplPTQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYigiQ291bnRzIChsb2cpIikgKyB4bGFiKCJEYXRlIikgKyAjIkRheXMgYmVmb3JlL1NpbmNlIFRha2VvZmYgaW4gQ29uZmlybWVkIE51bWJlcnMiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlcyggY29sb3IgPSBGQUxTRSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9nZW8ofmNvZGUpIAoKIApgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTJ9CnBfY29uZmlybWVkX2RlYXRoc190ZXN0X2J5X3N0YXRlX3VzCmBgYAoKSW5kaWEgYnkgU3RhdGUKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTIsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KCmhlYWQoaW5kaWFfZ3JpZDIpCgppbmRpYV9ncmlkMl9yZXggPC0gaW5kaWFfZ3JpZDIgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGFkbWluMF9uYW1lX29yaWdpbmFsPSJJbmRpYSIpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShhZG1pbjFfbmFtZV9vcmlnaW5hbD1uYW1lKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoYWRtaW4yX25hbWVfb3JpZ2luYWw9JycpICAlPiUKICAgIAogICAgICAgICAgICAgICAgICAgIG11dGF0ZShhZG1pbjBfbmFtZV9jbGVhbj1hZG1pbjBfbmFtZV9vcmlnaW5hbCAlPiUgcmV4X2NsZWFuKCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShhZG1pbjFfbmFtZV9jbGVhbj1hZG1pbjFfbmFtZV9vcmlnaW5hbCAlPiUgcmV4X2NsZWFuKCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShhZG1pbjJfbmFtZV9jbGVhbj1hZG1pbjJfbmFtZV9vcmlnaW5hbCAlPiUgcmV4X2NsZWFuKCkpICU+JQogICAgICAgICAgICAgICAgICAgIHJleF9hZG1pbl9mdW5jdGlvbigpCgp0ZW1wMSA8LSBkZl9zbG9wZXMgJT4lCiAgICAgICAgICBmaWx0ZXIoZ2lkICU+JSBzdHJfZGV0ZWN0KCJJTkRcXC5bMC05XXsxLDJ9XzEkIikgKSAlPiUKICAgICAgICAgIGxlZnRfam9pbihpbmRpYV9ncmlkMl9yZXggICkgJT4lIAogICAgICAgICAgbXV0YXRlKG5hbWVfdGV4dD0gYWRtaW4xX25hbWVfb3JpZ2luYWwgJT4lIGFzLmZhY3RvcigpKSAlPiUgI3NldCBpdCB0byB0aGUgc3RhdGUncyBuYW1lCiAgICAgICAgICBmaWx0ZXIoIWlzLm5hKG5hbWVfdGV4dCkpCnRlbXAyIDwtIHRlbXAxICU+JSBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgZmlsdGVyKCFkdXBsaWNhdGVkKGdpZF9nZW9uYW1laWRfd2lraWRhdGFfaWQpKSAlPiUgbXV0YXRlKG5hbWVfdGV4dD1uYW1lX3RleHQgJT4lIGFzLmZhY3RvcigpKQoKI3RfYWxsaWduZWQKcF9jb25maXJtZWRfZGVhdGhzX3Rlc3RfYnlfc3RhdGVfaW5kaWEgPC0gdGVtcDEgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZmlsdGVyKGdpZD09IlVTQSIpICU+JSAjanVzdCBhIHRlc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KCkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nX3lfaGF0KSwgY29sb3I9InJlZCIpICsgIyAjdCBhbGlnbmVkIGlzIGJyb2tlbiBmb3IgdGhlIFUuUy4gYW5kIHNvbWUgY291bnRyaWVzLCBhbGwgaW5maW5pdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzX2xvZ195X2hhdCksIGNvbG9yPSJibGFjayIpICsgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0KSwgY29sb3I9ImJsdWUiKSArICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoIkNvdmlkLTE5IEJ5IFUuUy4gU3RhdGU6IExvZyBUZXN0ZWQgKGJsdWUpIENvbmZpcm1lZCAocmVkKSwgRGVhdGggKGJsYWNrKSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3RleHQoZGF0YT10ZW1wMix4PTE4MjgyKzUwLHk9Ny41LGFlcyhsYWJlbD1uYW1lX3RleHQpLCBzaXplPTIuNSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvdW50cyAobG9nKSIpICsgeGxhYigiRGF0ZSIpICsgIyJEYXlzIGJlZm9yZS9TaW5jZSBUYWtlb2ZmIGluIENvbmZpcm1lZCBOdW1iZXJzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlcyggY29sb3IgPSBGQUxTRSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNFcnJvcjogT3RoZXIgdGhhbiAncm93JyBhbmQgJ2NvbCcsIHZhcmlhYmxlIG5hbWVzIG9mIGEgY3VzdG9tIGdyaWQgbXVzdCBiZWdpbiB3aXRoICdjb2RlJyBvciAnbmFtZScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9nZW8ofmNvZGUsIGdyaWQgPSBpbmRpYV9ncmlkMiApICAjX3JleCAlPiUgZmlsdGVyKGNvZGUsIHJvdywgY29sLCBuYW1lKQoKIApgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTJ9CnBfY29uZmlybWVkX2RlYXRoc190ZXN0X2J5X3N0YXRlX2luZGlhCmBgYAoKCgoKCgpUb21vcnJvdyBtb3JuaW5nIEkgdGhpbmsgbXkgam9iIGlzIHRvIGZpcnN0IGRpZmZlcmVuY2UgYWxsIG9mIHRoZXNlLiBIb3cgbWFueSB0ZXN0cywgaG93IG1hbnkgY29uZmlybWVkLCBob3cgbWFueSBkZWFkIGVhY2ggZGF5LiBGaW5kIHRoZSBsYWdzIGFuZCBsZWFkcyB3aXRoIHRoZSBoaWdoZXN0IGNvcnJlbGF0aW9uIGJldHdlZW4gdGhvc2UgdGhyZWUsIHBvc3NpYmx5IHZhcnlpbmcgYnkgY291bnRyeS4KCgoKCgoKCldoYXQgdGhpcyBnaXZlcyB1cyBpcyBhIG5pY2Ugbm9ybWFsaXplZCBkYXRhc2V0IHdoZXJlIHRoZSB0YXNrIGlzIHRvIHByZWRpY3QgdGhlIHNoYXBlIG9mIHRoYXQgZGlzdHJpYnV0aW9uLiBXZSBjb3VsZCB0cnkgdG8gcHJlZGljdCB0aW1lIHVudGlsIHRoZSB0YWtlb2ZmLCB0aGUgaW50ZW5zaXR5IG9mIHRoZSBncm93dGggYXQgdGhlIHRha2VvZmYgcG9pbnQsIHRoZSB0aW1lIHVudGlsIGl0IHJldHVybnMgdG8gemVybywgdGhlIGFyZWEgdW5kZXIgdGhlIGN1cnZlLCBvciBldmVyeSBub29rIGFuZCBjaGFuZ2UuCgoKSG93IGRvZXMgdGVzdGluZyB2YXJ5IG92ZXIgdGhpcz8KCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyLCBlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CgpwX3RfYWxsaWduZWRfdGVzdGVkX3Blb3BsZSA8LSBkZl9zbG9wZXMgJT4lIG11dGF0ZShncm91cD1wYXN0ZSh3aWtpZGF0YV9pZCkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZSggYWVzKHg9dF9hbGxpZ25lZCAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXRfcGVyY2VudF9jaGFuZ2VfeV9oYXQsIGdyb3VwPWdyb3VwLCBjb2xvcj13aWtpZGF0YV9pZCksIGFscGhhPTEpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKCJQZXJjZW50IERheSBvbiBEYXkgSW5jcmVhc2UgaW4gVGVzdGluZyBieSBBbGxpZ25lZCBUIikgKyB5bGltKDAsMTAwKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2doaWdobGlnaHQod2lraWRhdGFfaWQgJWluJSBjKCdRMzAnLCdRMTQzOScsJ1E2NjgnLCdRODg0JywnUTE2ODYxJywnUTE1OScsJ1EzOCcpLCB1bmhpZ2hsaWdodGVkX3BhcmFtcz1saXN0KGFscGhhPS41KSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fc21vb3RoKCBhZXMoeD10X2FsbGlnbmVkICwgeT1jb25maXJtZWRfbG9nX3lfaGF0X3BlcmNlbnRfY2hhbmdlX3lfaGF0KSwgc3BhbiA9IDAuMDUpICsgeGxpbSgtNTAsMTAwKSAKCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMix3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0V9CnBfdF9hbGxpZ25lZF90ZXN0ZWRfcGVvcGxlCmBgYAoKClBsb3Qgc29tZSBzcGVjaWZpYyBjb3VudHJpZXMKCgpgYGB7cn0KCmRmX3Nsb3BlcyAlPiUgZmlsdGVyKCFpcy5uYSh0ZXN0ZWRfcGVvcGxlKSkgJT4lIGNvdW50KHdpa2lkYXRhX2lkKSAjMjkyIHBsYWNlcyB3aXRoIHRlc3RpbmcgaW5mb3JtYXRpb24KCmRmX3Nsb3BlcyAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTMwIikgJT4lIGdncGxvdCgpICsgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZCkpICsgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGUpKQoKZGZfc2xvcGVzICU+JSBmaWx0ZXIod2lraWRhdGFfaWQ9PSJRMzAiKSAlPiUgZ2dwbG90KCkgKyBnZW9tX2xpbmUoYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkX2xvZ195X2hhdCkpICsgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0KSkKCmRmX3Nsb3BlcyAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTMwIikgJT4lIGdncGxvdCgpICsgZ2VvbV9saW5lKGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZC90ZXN0ZWRfcGVvcGxlKSkgCgoKZGZfc2xvcGVzICU+JSBtdXRhdGUoY29uZmlybWVkX292ZXJfdGVzdGVkX3Blb3BsZT1jb25maXJtZWQvdGVzdGVkX3Blb3BsZSkgJT4lIHB1bGwoY29uZmlybWVkX292ZXJfdGVzdGVkX3Blb3BsZSkgJT4lIHN1bW1hcnkoKQpkZl9zbG9wZXMgJT4lIG11dGF0ZShjb25maXJtZWRfb3Zlcl90ZXN0ZWRfcGVvcGxlPWNvbmZpcm1lZC90ZXN0ZWRfcGVvcGxlKSAlPiUgcHVsbChjb25maXJtZWRfb3Zlcl90ZXN0ZWRfcGVvcGxlKSAlPiUgcXVhbnRpbGUocHJvYnMgPSBzZXEoMCwgMSwgMC4xKSwgbmEucm09VCkgIzkwdGggcGVyY2VudGlhbCBpcyAsMjMKCmRmX3Nsb3BlcyAlPiUgZ2dwbG90KCkgKyBnZW9tX2xpbmUoYWVzKHg9dF9hbGxpZ25lZCwgeT1jb25maXJtZWQvdGVzdGVkX3Blb3BsZSwgY29sb3I9d2lraWRhdGFfaWQpLCBhbHBoYT0uMikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ2hpZ2hsaWdodCh3aWtpZGF0YV9pZCAlaW4lIGMoJ1EzMCcsJ1ExNDM5JywnUTY2OCcsJ1E4ODQnLCdRMTY4NjEnLCdRMTU5JywnUTM4JyksIHVuaGlnaGxpZ2h0ZWRfcGFyYW1zPWxpc3QoYWxwaGE9LjUpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9zbW9vdGgoIGFlcyh4PXRfYWxsaWduZWQgLCB5PWNvbmZpcm1lZC90ZXN0ZWRfcGVvcGxlKSwgc3BhbiA9IDAuMDUpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxpbSgtNSwxMDApICsgeWxpbSgwLC4yNSkgKyB0aGVtZV9idygpICN0aGVyZSBhcmUgc29tZSBvdXRsaWFycyBub3J0aCBvZiAxMAoKCm9wdGlvbnMoZ2doaWdobGlnaHRfbWF4X2xhYmVscyA9IDYwKQpkZXRhY2goZ2doaWdobGlnaHQpCmxpYnJhcnkoZ2doaWdobGlnaHQpCmxpYnJhcnkoZGF0YS50YWJsZSkKZ2VvbmFtZXMgPC0gZnJlYWQoIi9tZWRpYS9za3luZXQyLzkwNTg4NGYwLTc1NDYtNDI3My05MDYxLTEyYTc5MDgzMGJlYi9yd2RfZ2l0aHViX3ByaXZhdGUvTkVTU2NvdmlkMTkvZGF0YV90ZW1wL2FsbENvdW50cmllcy50eHQiLCBzZXA9Ilx0IikgJT4lIG11dGF0ZV9pZihpcy5udW1lcmljLGFzLmNoYXJhY3RlcikgJT4lIG11dGF0ZV9pZihpcy5mYWN0b3IsYXMuY2hhcmFjdGVyKQpkaW0oZ2VvbmFtZXMpICMxMiwwMDYsNDI2CgpnZW9uYW1lc19zbWFsbCA8LSBnZW9uYW1lcyAlPiUgZHBseXI6OnNlbGVjdChnZW9uYW1laWQ9VjEsIG5hbWVfdGV4dD1WMikgJT4lIGlubmVyX2pvaW4oIGxoc19sb25nX2NsZWFuX2ltcHV0ZWQgJT4lIGRwbHlyOjpzZWxlY3QoZ2VvbmFtZWlkKSAlPiUgZGlzdGluY3QoKSApCmRpbShnZW9uYW1lc19zbWFsbCkKCgpkZl9zbG9wZXMgJT4lIGxlZnRfam9pbihnZW9uYW1lc19zbWFsbCAgKSAlPiUgbXV0YXRlKG5hbWVfdGV4dCAlPiUgYXMuZmFjdG9yKCkpICU+JSBmaWx0ZXIoZ2lkICU+JSBzdHJfZGV0ZWN0KCJVU0FcXC5bMC05XXsxLDJ9XzEkIikpICU+JQogICAgICAgICAgIGdncGxvdCgpICsgZ2VvbV9saW5lKGFlcyh4PXRfYWxsaWduZWQsIHk9Y29uZmlybWVkX2xvZ195X2hhdCwgY29sb3I9bmFtZV90ZXh0KSwgYWxwaGE9LjIpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2doaWdobGlnaHQobWF4X2hpZ2hsaWdodCA9IDEwMEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2lkICU+JSBzdHJfZGV0ZWN0KCJVU0EiKSwgdW5oaWdobGlnaHRlZF9wYXJhbXM9bGlzdChhbHBoYT0uMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlX2RpcmVjdF9sYWJlbD1UKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9zbW9vdGgoIGFlcyh4PXRfYWxsaWduZWQgLCB5PWNvbmZpcm1lZF9sb2dfeV9oYXQsIHNwYW4gPSAwLjA1KSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGltKC01LDEwMCkgKyAjeWxpbSgwLC4yNSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICN0aGVyZSBhcmUgc29tZSBvdXRsaWFycyBub3J0aCBvZiAxMAoKZGZfc2xvcGVzICU+JSBsZWZ0X2pvaW4oZ2VvbmFtZXNfc21hbGwgICkgJT4lIG11dGF0ZShuYW1lX3RleHQgJT4lIGFzLmZhY3RvcigpKSAlPiUgZmlsdGVyKGdpZCAlPiUgc3RyX2RldGVjdCgiVVNBXFwuWzAtOV17MSwyfV8xJCIpKSAlPiUKICAgICAgICAgICBnZ3Bsb3QoKSArIGdlb21fbGluZShhZXMoeD10X2FsbGlnbmVkLCB5PXRlc3RlZF9wZW9wbGVfbG9nX3lfaGF0LCBjb2xvcj1uYW1lX3RleHQpLCBhbHBoYT0uMikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ2hpZ2hsaWdodChtYXhfaGlnaGxpZ2h0ID0gMTAwTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnaWQgJT4lIHN0cl9kZXRlY3QoIlVTQSIpLCB1bmhpZ2hsaWdodGVkX3BhcmFtcz1saXN0KGFscGhhPS4xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VfZGlyZWN0X2xhYmVsPVQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3Ntb290aCggYWVzKHg9dF9hbGxpZ25lZCAsIHk9dGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQsIHNwYW4gPSAwLjA1KSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGltKC01LDE1MCkgKyAjeWxpbSgwLC4yNSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV9idygpICN0aGVyZSBhcmUgc29tZSBvdXRsaWFycyBub3J0aCBvZiAxMAoKZGZfc2xvcGVzICU+JSBsZWZ0X2pvaW4oZ2VvbmFtZXNfc21hbGwgICkgJT4lIG11dGF0ZShuYW1lX3RleHQgJT4lIGFzLmZhY3RvcigpKSAlPiUKICAgICAgICAgICBnZ3Bsb3QoKSArIGdlb21fbGluZShhZXMoeD10X2FsbGlnbmVkLCB5PWV4cChjb25maXJtZWRfbG9nX3lfaGF0KS9leHAodGVzdGVkX3Blb3BsZV9sb2dfeV9oYXQpLCBjb2xvcj1uYW1lX3RleHQpLCBhbHBoYT0uMikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ2hpZ2hsaWdodChtYXhfaGlnaGxpZ2h0ID0gMTAwTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnaWQgJT4lIHN0cl9kZXRlY3QoIlVTQSIpLCB1bmhpZ2hsaWdodGVkX3BhcmFtcz1saXN0KGFscGhhPS4xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VfZGlyZWN0X2xhYmVsPVQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3Ntb290aCggYWVzKHg9dF9hbGxpZ25lZCAsIHk9ZXhwKGNvbmZpcm1lZF9sb2dfeV9oYXQpL2V4cCh0ZXN0ZWRfcGVvcGxlX2xvZ195X2hhdCksIHNwYW4gPSAwLjA1KSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGltKC01LDEwMCkgKyB5bGltKDAsLjI1KSArIHRoZW1lX2J3KCkgI3RoZXJlIGFyZSBzb21lIG91dGxpYXJzIG5vcnRoIG9mIDEwCgojd2UgbWlnaHQgbmVlZCB0byBzd2l0Y2ggdGhpcyB0byBmZC4gQmVjYXVzZSBpdCdzIHRoZSBwZXJjZW50IG9mIHRoZSBuZXcgdGVzdHMgY29taW5nIGJhY2sgcG9zaXRpdmUgbm90IHRoZSBvbGQgb25lcy4KCiNSZW1pbmQgb3Vyc2VsdmVzIGludGVycHJldGF0aW9ucyB3aGVuIHdlIGxocwojaHR0cHM6Ly9kYXRhLmxpYnJhcnkudmlyZ2luaWEuZWR1L2ludGVycHJldGluZy1sb2ctdHJhbnNmb3JtYXRpb25zLWluLWEtbGluZWFyLW1vZGVsLwoKYGBgCgoKCgoKYGBge3IsIGV2YWw9Rn0KCmxtMSA8LSBsbShkZWF0aHMgfiAgY29uZmlybWVkLGRhdGE9bGhzX2xvbmdfbWVkaWFuICU+JSBmaWx0ZXIoQ0ZSPDEpKQpsbTIgPC0gbG0oZGVhdGhzIH4gdGVzdGVkX3Blb3BsZSArIGNvbmZpcm1lZCxkYXRhPWxoc19sb25nX21lZGlhbiAlPiUgZmlsdGVyKENGUjwxKSkKCmxpYnJhcnkoZ2dSYW5kb21Gb3Jlc3RzKTsgI2luc3RhbGwucGFja2FnZXMoJ2dnUmFuZG9tRm9yZXN0cycpCnJmMSA8LSByZnNyYyhkZWF0aHN+IGNvbmZpcm1lZCwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9bGhzX2xvbmdfbWVkaWFuICU+JSBmaWx0ZXIoQ0ZSPDEpICU+JSBhcy5kYXRhLmZyYW1lKCkgKQpnZ19lIDwtIGdnX2Vycm9yKHJmMSkKZ2dfdiA8LSBnZ192YXJpYWJsZShyZjEpCnBsb3QoZ2dfdiwgcGFuZWw9VFJVRSwgc2U9Ljk1LCBzcGFuPTEuMiwgYWxwaGE9LjQpIAoKcmYxIDwtIHJmc3JjKGRlYXRoc34gY29uZmlybWVkICsgdGVzdGVkX3Blb3BsZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9bGhzX2xvbmdfbWVkaWFuICU+JSBmaWx0ZXIoQ0ZSPDEpICU+JSBhcy5kYXRhLmZyYW1lKCkgKQpnZ19lIDwtIGdnX2Vycm9yKHJmMSkKZ2dfdiA8LSBnZ192YXJpYWJsZShyZjEpCnBsb3QoZ2dfdiwgcGFuZWw9VFJVRSwgc2U9Ljk1LCBzcGFuPTEuMiwgYWxwaGE9LjQpCgoKcmYyIDwtIHJmc3JjKENGUiB+ICB0ZXN0ZWRfcGVvcGxlX2xvZywKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9bGhzX2xvbmdfbWVkaWFuICU+JSAKICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShDRlI9ZGVhdGhzL2NvbmZpcm1lZCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUodGVzdGVkX3Blb3BsZV9sb2c9bG9nKHRlc3RlZF9wZW9wbGUrMSkpICU+JQogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKENGUjwxKSAlPiUgYXMuZGF0YS5mcmFtZSgpCiAgICAgICAgICAgICApCmdnX3YgPC0gZ2dfdmFyaWFibGUocmYyKQpwbG90KGdnX3YsIHBhbmVsPVRSVUUsIHNlPS45NSwgc3Bhbj0xLjIsIGFscGhhPS40KQoKcmYyIDwtIHJmc3JjKENGUiB+ICB0ZXN0ZWRfcGVvcGxlX2xvZyArIGNvbmZpcm1lZF9sb2csCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWxoc19sb25nX21lZGlhbiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoQ0ZSPWRlYXRocy9jb25maXJtZWQpICU+JQogICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nPWxvZyh0ZXN0ZWRfcGVvcGxlKzEpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nPWxvZyhjb25maXJtZWQrMSkpICU+JQogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKENGUjwxKSAlPiUgYXMuZGF0YS5mcmFtZSgpCiAgICAgICAgICAgICApCmdnX3YgPC0gZ2dfdmFyaWFibGUocmYyKQpwbG90KGdnX3YsIHBhbmVsPVRSVUUsIHNlPS45NSwgc3Bhbj0xLjIsIGFscGhhPS40KQoKCiNUaHJvdyBpbiB0aW1lCnJmMyA8LSByZnNyYyhDRlIgfiAgcG9zaXRpdmVfcGVyYyArIHRlc3RlZF9wZW9wbGVfbG9nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWxoc19sb25nX21lZGlhbiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShDRlI9ZGVhdGhzL2NvbmZpcm1lZCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShwb3NpdGl2ZV9wZXJjPWNvbmZpcm1lZC90ZXN0ZWRfcGVvcGxlKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHRlc3RlZF9wZW9wbGVfbG9nPWxvZyh0ZXN0ZWRfcGVvcGxlKzEpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2c9bG9nKGNvbmZpcm1lZCsxKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihDRlI8MSkgJT4lIGFzLmRhdGEuZnJhbWUoKQogICAgICAgICAgICAgKQpnZ192IDwtIGdnX3ZhcmlhYmxlKHJmMykKcGxvdChnZ192LCBwYW5lbD1UUlVFLCBzZT0uOTUsIHNwYW49MS4yLCBhbHBoYT0uNCkKCnBhcnRpYWxfQm9zdG9uIDwtIHBsb3QudmFyaWFibGUocmYzLApwYXJ0aWFsPVRSVUUsIHNvcnRlZD1GQUxTRSwKc2hvdy5wbG90cyA9IEZBTFNFICkKCmdnX3AgPC0gZ2dfcGFydGlhbChwYXJ0aWFsX0Jvc3RvbikKcGxvdChnZ19wLCBwYW5lbD1UUlVFLCBwb2ludHMgPSBGICkKCgpjb3BwZXJfY3RzIDwtcXVhbnRpbGVfcHRzKGxoc19sb25nX21lZGlhbiR0ZXN0ZWRfcGVvcGxlX2xvZywgZ3JvdXBzID0gNiwgaW50ZXJ2YWxzID0gVFJVRSkKcGFydGlhbF9jb3Bsb3RfQm9zdG9uIDwtIGdnX3BhcnRpYWxfY29wbG90KHJmMiwgeHZhcj0iY29uZmlybWVkX2xvZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzPXJtX2dycCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93LnBsb3RzPUZBTFNFKQoKCgpzdW1tYXJ5KGxoc19sb25nX21lZGlhbiRDRlIpCgpsaHNfbG9uZ19tZWRpYW4gJT4lIGZpbHRlcihjb25maXJtZWQ+MTApICU+JSBmaWx0ZXIoQ0ZSPDEpICU+JSBwdWxsKENGUikgJT4lIHN1bW1hcnkoKSAjMC4wMjk3Mjk3ICB0aGF0J3MgYSBtZWRpYW4gQ0ZSIG9mIGFib3V0IDMlCmxoc19sb25nX21lZGlhbiAlPiUgZmlsdGVyKGNvbmZpcm1lZD4xMCkgJT4lIGZpbHRlcihDRlI8MSkgJT4lIHB1bGwoQ0ZSKSAlPiUgaGlzdChicmVha3M9NTApCgpsaHNfbG9uZ19tZWRpYW4gJT4lIGZpbHRlcihjb25maXJtZWQ+MTApICU+JSBmaWx0ZXIoQ0ZSPDEpICU+JSBnZ3Bsb3QoYWVzKHg9Q0ZSKSkgKyBnZW9tX2RlbnNpdHkoKQoKCmBgYAoKCgpgYGB7ciwgZXZhbD1GfQojVGhpcyBjb2RlIGlzIG5vdyBkZXByaWNhdGVkIGluIGZhdm9yIG9mIHRoZSB0cmVlIGJhc2UgbWV0aG9kIGFib3ZlCgpwbGFjZXMgPC0gbGhzX2xvbmdfY2xlYW4kd2lraWRhdGFfaWQgJT4lIHVuaXF1ZSgpICU+JSBuYS5vbWl0KCkgOyBsZW5ndGgocGxhY2VzKQpkYXRhc2V0cyA8LSBsaHNfbG9uZ19jbGVhbiRkYXRhc2V0ICU+JSB1bmlxdWUoKSAlPiUgbmEub21pdCgpIDsgdGFibGUoZGF0YXNldCkKCnRlbXBfbGlzdCA8LSBsaXN0KCkKZm9yKHAgaW4gcGxhY2VzKXsKICAgIHByaW50KHApCiAgICBmb3IoZCBpbiBkYXRhc2V0cyl7CiAgICAgIHRlbXAgPC0gTlVMTAogICAgICB0ZW1wIDwtIGxoc19sb25nX2NsZWFuICU+JSAKICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKGRhdGFzZXQgJWluJSBkKSAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdpa2lkYXRhX2lkICVpbiUgcCkgJT4lIAogICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nPWxvZyhjb25maXJtZWQrMSkpICU+JQogICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfbG9nPWxvZyhkZWF0aHMrMSkpICU+JQogICAgICAgICAgICAgIG11dGF0ZSh0ZXN0ZWRfcGVvcGxlX2xvZz1sb2codGVzdGVkX3Blb3BsZSsxKSkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHQ9IGFzLm51bWVyaWMoZGF0ZV9hc2RhdGUpIC0gbWluKGFzLm51bWVyaWMoZGF0ZV9hc2RhdGUpKSArMSAgKSAlPiUgI3N0YXJ0IGF0IDEgdG8gbWFrZSBpbmRleGluZyBlYXNpZXIKICAgICAgICAgICAgICBtdXRhdGUoaT0gcm93X251bWJlcigpICApICMgYWN0dWFsbHkgbmVlZCB0aGlzCiAgICAgICAgCiAgICAgIGlfb3JpZ2luYWwgPC0gdGVtcCRpCiAgICAgIAogICAgICBpZiggbnJvdyh0ZW1wKT09MCApIHsgbmV4dH0gI3ByaW50KCJlcnJvciIpOwogICAgICBwcmludChwKQogICAgICAKICAgICAgI2JwIDwtIGJyZWFrcG9pbnRzKGNvbmZpcm1lZF9sb2cgfiAxLCBkYXRhPXRlbXApCiAgICAgIGJwIDwtIE5VTEwKICAgICAgbG0xIDwtIE5VTEwKICAgICAgeV9oYXQgPC0gTkEKICAgICAgY2RmIDwtIE5VTEwKICAgICAgdHJ5KHsKICAgICAgICAgICAgI2lmIGl0IGZhaWxzIGZhbGwgYmFjayB0byBqdXN0IGEgbG0KICAgICAgICBsbTEgPC0gbG0oY29uZmlybWVkX2xvZyB+IDEgKyB0LCBkYXRhPXRlbXApCiAgICAKICAgICAgICBjZGYgPC0gZGF0YS5mcmFtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICB0PSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maXJtZWRfbG9nX2ludGVyY2VwdD0gY29lZihsbTEpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpcm1lZF9sb2dfc2xvcGU9IGNvZWYobG0xKVsyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maXJtZWRfbG9nX3Nsb3BlX2JyZWFrPTAKICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgY29uZmlybWVkX2xvZ195X2hhdD1maXR0ZWQudmFsdWVzKGxtMSkKICAgICAgfSkKICAgICAgCiAgICAgIHRyeSh7CiAgICAgICAgYnAgPC0gYnJlYWtwb2ludHMoY29uZmlybWVkX2xvZyB+IDEgKyB0LCBkYXRhPXRlbXAsIGg9MykKICAgICAgICAKICAgICAgICBjZGYgPC0gZGF0YS5mcmFtZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBpPSBjKDEsYnAkYnJlYWtwb2ludHMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maXJtZWRfbG9nX2ludGVyY2VwdD0gY29lZihicClbLDFdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpcm1lZF9sb2dfc2xvcGU9IGNvZWYoYnApWywyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maXJtZWRfbG9nX3Nsb3BlX2JyZWFrPTEKICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgY29uZmlybWVkX2xvZ195X2hhdD1maXR0ZWQudmFsdWVzKGJwKQogICAgICB9KQogICAgICAKICAgICAgdHJ5KHsKICAgICAgICB0ZW1wMiA8LSB0ZW1wCiAgICAgICAgdGVtcDIkY29uZmlybWVkX2xvZ195X2hhdCA8LSBOQQogICAgICAgIHRlbXAyJGNvbmZpcm1lZF9sb2dfeV9oYXQgPC0gY29uZmlybWVkX2xvZ195X2hhdAogICAgICAgIAogICAgICAgIHRlbXAyIDwtIHRlbXAyICU+JSAKICAgICAgICAgICAgICAgIGxlZnRfam9pbihjZGYpIAogICAgICAgIHE9cGFzdGUwKHAsIl8iLGQpCiAgICAgICAgdGVtcDIgPC0gdGVtcDIgJT4lIAogICAgICAgICAgICAgICAgICBleHBhbmQoZGF0YXNldCwgZ2lkLGdlb25hbWVpZCwgd2lraWRhdGFfaWQsdD1taW4odGVtcCR0KTptYXgodGVtcCR0KSkgJT4lICNleHBhbmQgdGhpcyB0byBpbmNsdWRlIGFsbCB0aGUgdCAKICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKHRlbXAyKSAlPiUgCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXRlX2FzZGF0ZT1taW4oZGF0ZV9hc2RhdGUsIG5hLnJtPVQpLTErdCkgJT4lICNnbyBiYWNrIGludGVycCBkYXRlIGFnYWluCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nX3Nsb3BlX2JyZWFrID0gY29uZmlybWVkX2xvZ19zbG9wZV9icmVhayAlPiUgcmVwbGFjZV9uYSgwKSAlPiUgY3Vtc3VtKCkgKSAlPiUKICAgICAgICAgICAgICAgICAgZmlsbChjb25maXJtZWRfbG9nX2ludGVyY2VwdCkgJT4lCiAgICAgICAgICAgICAgICAgIGZpbGwoY29uZmlybWVkX2xvZ19zbG9wZSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbG9nX3lfaGF0PSBjb25maXJtZWRfbG9nX2ludGVyY2VwdCArIGNvbmZpcm1lZF9sb2dfc2xvcGUqdCApICU+JSAKICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2dfc2xvcGVfcGVyY2VudF9jaGFuZ2UgPSByb3VuZCgoZXhwKGNvbmZpcm1lZF9sb2dfc2xvcGUpLTEpKjEwMCwyKSkgCgogICAgICAgIHRlbXBfbGlzdFtbYXMuY2hhcmFjdGVyKHEpXV0gPC0gdGVtcDIKICAgICAgfSkKICAgICAgI2lmKCBpcy5uYSggdGVtcF9saXN0W1thcy5jaGFyYWN0ZXIocSldXSR5X2hhdCkgKSB7cHJpbnQoImVycm9yIik7IGJyZWFrfQogICAgfQp9CiMiMTMwNTUiCnRlbXBfZGYgPC0gYmluZF9yb3dzKHRlbXBfbGlzdCkKZGltKHRlbXBfZGYpICNiaWdnZXIgYmVjYXVzZSB3ZSdyZSBpbnRlcnBvbGF0aW5nIG5vdwoKIyBpbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS9tdWx0aWRwbHlyIikKCmxpYnJhcnkobXVsdGlkcGx5cikKbGlicmFyeShkcGx5ciwgd2Fybi5jb25mbGljdHMgPSBGQUxTRSkKI2NsdXN0ZXIgPC0gbmV3X2NsdXN0ZXIoNCkKCiNuZWVkIHRvIHN1cHJlc3MgbWVzc2FnZXMKcmV4X2Z1bmN0aW9uIDwtIGZ1bmN0aW9uKHgpewogIHRlbXA9ZGF0YS5mcmFtZShjb25maXJtZWRfbG9nX3Nsb3BlPXgpCiAgdHJ5Q2F0Y2goewogICAgI2lmIHRoZXJlJ3MgYW4gTkEgaW4geCB3ZSBnZXQgYW4gZXJyb3IgYmVjYXVzZSBicmVha3BvaW50cyBpcyBvbmUgc2hvcnQKICAgIHByZWRpY3Rpb24gPC0gYnJlYWtwb2ludHMoZm9ybXVsYT1jb25maXJtZWRfbG9nX3Nsb3BlIH4gMSwgZGF0YT10ZW1wLCBoPTMpICU+JSBmaXR0ZWQudmFsdWVzKCkKICAgIHJlc3VsdD1yZXAoTkEsIGxlbmd0aCh4KSApCiAgICByZXN1bHRbIWlzLm5hKHgpXSA8LXByZWRpY3Rpb24KICAgIHJldHVybihyZXN1bHQpCiAgICAKICB9LCBlcnJvcj1mdW5jdGlvbihlKXt9KQogIAogIHJldHVybiggcmVwKE5BLCBsZW5ndGgoeCkgKSApCiAgICAgICAgIAp9CiNkaWRuJ3QgdGFrZSB0b28gbG9uZyBub3cKCiNsaWJyYXJ5KG11bHRpZHBseXIpCiNsaWJyYXJ5KGRwbHlyLCB3YXJuLmNvbmZsaWN0cyA9IEZBTFNFKQojY2x1c3RlciA8LSBuZXdfY2x1c3Rlcig0KQoKbGlicmFyeSh0aWN0b2MpCnRpYygpCmxpYnJhcnkoc3RydWNjaGFuZ2UpCnRlc3QgPC0gdGVtcF9kZiAlPiUgaGVhZCgyMDAwMCkKdGVzdDMgPC0gdGVzdCAlPiUgCiAgICAgICAgICAgICAgICBncm91cF9ieSh3aWtpZGF0YV9pZCkgJT4lIAogICAgICAgICAgICAgICAgI3BhcnRpdGlvbihjbHVzdGVyKSAlPiUKICAgICAgICAgICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgICAgI211dGF0ZSggY29uZmlybWVkX2xvZ19zbG9wZV95X2hhdCA9IGJyZWFrcG9pbnRzKGZvcm11bGE9Y29uZmlybWVkX2xvZ19zbG9wZSB+IDEsIGRhdGE9LiApICU+JSBmaXR0ZWQudmFsdWVzKCkgKSAlPiUgCiAgICAgICAgICAgICAgICBtdXRhdGUoIGNvbmZpcm1lZF9sb2dfc2xvcGVfeV9oYXQgPSByZXhfZnVuY3Rpb24oY29uZmlybWVkX2xvZ19zbG9wZSkgKSAlPiUgICNmYWlscyBvbiB0aGUgY2x1c3RlcgogICAgICAgICAgICAgICAgdW5ncm91cCgpICMlPiUKICAgICAgICAgICAgICAgICNjb2xsZWN0KCkKdG9jKCkgIzQ4IHNlY29uZHMgZm9yIDEwayAjMTIyIHNlY29uZHMgZm9yIDIwawoKc2F2ZVJEUyh0ZW1wX2RmLCAiL21lZGlhL3NreW5ldDIvOTA1ODg0ZjAtNzU0Ni00MjczLTkwNjEtMTJhNzkwODMwYmViL3J3ZF9naXRodWJfcHJpdmF0ZS9ORVNTY292aWQxOS9kYXRhX3RlbXAvbGhzX2xvbmdfaW50ZXJwb2xhdGVkLlJkcyIpCgpgYGAKCgoKCgoKCgoKYGBge3IsIGV2YWw9RiwgZWNobz1GLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxlcnJvcj1GQUxTRX0KCiNIZXJlIGlzIHdoZXJlIEkgd29ya2VkIG91dCB0aGUgaWRlYSBvZiBmaXR0aW5nIHBpZWNld2lzZSBsaW5lYXIgZnVuY3Rpb25zIHRvIGVhY2ggZGF0YXNldCBpbmRlcGVuZGVudGx5LiBJdCdzIG5vdyByZXBsYWNlZCB3aXRoIGEgZnVsbHkgYXV0b21hdGVkIHBpcGxpbmUgYmFzZWQgb24gdHJlZXMuCgpjb3VudF9kYXRhc2V0cyA8LSBsaHNfbG9uZ19jbGVhbiAlPiUgZHBseXI6OnNlbGVjdCh3aWtpZGF0YV9pZCwgZGF0YXNldCkgJT4lIGRpc3RpbmN0KCkgJT4lIGNvdW50KHdpa2lkYXRhX2lkKQoKZm9ybXVsYSA9IGNvbmZpcm1lZF9sb2cgfiAxICsgZGF0ZV9yYW5rICMrIEkoZGF0ZV9yYW5rXjIpICsgSShkYXRlX3JhbmteMykKaD01CiNiZXhhciBjb3VudHkKbGlicmFyeShzdHJ1Y2NoYW5nZSkgOyAjaW5zdGFsbC5wYWNrYWdlcygnc3RydWNjaGFuZ2UnKQp0ZW1wIDwtIGxoc19sb25nX2NsZWFuICU+JSBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkICVpbiUgIlExNjg2MSIpICU+JSAgbXV0YXRlKGNvbmZpcm1lZF9sb2c9bG9nKGNvbmZpcm1lZCsxKSkgJT4lCiAgICAgICAgbXV0YXRlKGRhdGVfcmFuaz0gYXMubnVtZXJpYyhkYXRlX2FzZGF0ZSkgLSBtaW4oYXMubnVtZXJpYyhkYXRlX2FzZGF0ZSkpKSAgCgp0YWJsZSh0ZW1wJGRhdGFzZXQpCgp0ZW1wX3VzYWZhY3RzIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0idXNhZmFjdHMiKQpicF91c2FmYWN0cyA8LSBicmVha3BvaW50cyhmb3JtdWxhLCBkYXRhPXRlbXBfdXNhZmFjdHMsaD1oKQp0ZW1wX3VzYWZhY3RzJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMoYnBfdXNhZmFjdHMpCnRlbXBfdXNhZmFjdHMkZ3JvdXBzIDwtIDA7IHRlbXBfdXNhZmFjdHMkZ3JvdXBzW2JwX3VzYWZhY3RzJGJyZWFrcG9pbnRzKzFdIDwtIDEgOyB0ZW1wX3VzYWZhY3RzJGdyb3VwcyA8LSBjdW1zdW0odGVtcF91c2FmYWN0cyRncm91cHMpKzEKCnRlbXBfbnl0IDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0ibnl0IikKYnBfbnl0IDwtIGJyZWFrcG9pbnRzKGZvcm11bGEsIGRhdGE9dGVtcF9ueXQsaD1oKQp0ZW1wX255dCR5X2hhdCA8LSBmaXR0ZWQudmFsdWVzKGJwX255dCkKdGVtcF9ueXQkZ3JvdXBzIDwtIDA7IHRlbXBfbnl0JGdyb3Vwc1ticF9ueXQkYnJlYWtwb2ludHMrMV0gPC0gMSA7IHRlbXBfbnl0JGdyb3VwcyA8LSBjdW1zdW0odGVtcF9ueXQkZ3JvdXBzKSsxCgoKdGVtcF9DU1NFIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iQ1NTRSIpCmJwX0NTU0UgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX0NTU0UsaD1oKQp0ZW1wX0NTU0UkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9DU1NFKQp0ZW1wX0NTU0UkZ3JvdXBzIDwtIDA7IHRlbXBfQ1NTRSRncm91cHNbYnBfQ1NTRSRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF9DU1NFJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9DU1NFJGdyb3VwcykrMQoKdGVtcF9iaW5nIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iYmluZyIpCmJwX2JpbmcgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX2JpbmcsaD1oKSAjdGhpcyBmYWlscyBiYyB0b28gZmV3CmxtX2JpbmcgPC1sbShmb3JtdWxhLCBkYXRhPXRlbXBfYmluZykKdGVtcF9iaW5nJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMobG1fYmluZykKdGVtcF9iaW5nJGdyb3VwcyA8LTEKCnRlbXBfZGYgPC0gYmluZF9yb3dzKHRlbXBfbnl0LCB0ZW1wX0NTU0UsIHRlbXBfYmluZywgdGVtcF91c2FmYWN0cykgICU+JSAKICAgICAgICAgICAgYXJyYW5nZShkYXRhc2V0LGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgICAgbXV0YXRlKGdyb3Vwcz1wYXN0ZShkYXRhc2V0LGdyb3VwcykpCgp0ZW1wX2RmMiA8LSBiaW5kX3Jvd3ModGVtcF9ueXQsIHRlbXBfQ1NTRSwgdGVtcF9iaW5nLCB0ZW1wX3VzYWZhY3RzKSAlPiUgCiAgICAgICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICAgZ3JvdXBfYnkoZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgIHN1bW1hcmlzZSh5X2hhdF9tZWFuPW1lYW4oeV9oYXQsIG5hLnJtPVQpKSAlPiUKICAgICAgICAgICAgbXV0YXRlKGdyb3Vwcz05OSkKCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSkgKwogICBnZW9tX2xpbmUoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXBzKSkgKwogICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJCZXhhciBDb3VudHkgKFExNjg2MSkgQ29uZmlybWVkIikKCgoKIyMjIyMKI0NoaW5hIFExNDgKdGVtcCA8LSBsaHNfbG9uZ19jbGVhbiAlPiUgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lIAogICAgICAgIGZpbHRlcih3aWtpZGF0YV9pZCAlaW4lICJRMTQ4IikgJT4lIAogICAgICAgIGdyb3VwX2J5KGRhdGFzZXQsIGRhdGVfYXNkYXRlKSAlPiUKICAgICAgICAgIHN1bW1hcmlzZShjb25maXJtZWQ9bWF4KGNvbmZpcm1lZCwgbmEucm09VCkgKSAlPiUgI3RoaXMgaXMgYSBwcm9ibGVtIGR1cGVzIHdpdGggdGhlIHNhbWUgZGF0ZSAgI3RoaXMgZml4ZXMgYSBsb3Qgb2YgdGhpbmdzIGJ1dCB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgdGhlIG9yaWdpbiBvZiB0aGlzIHByb2JsZW0KICAgICAgICB1bmdyb3VwKCkgJT4lCiAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9sb2c9bG9nKGNvbmZpcm1lZCsxKSkgJT4lIAogICAgICAgIG11dGF0ZShkYXRlX3Jhbms9IGFzLm51bWVyaWMoZGF0ZV9hc2RhdGUpIC0gbWluKGFzLm51bWVyaWMoZGF0ZV9hc2RhdGUpKSkgIAoKCnRlbXBfd2lraXBlZGlhIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0id2lraXBlZGlhIikKYnBfd2lraXBlZGlhIDwtIGJyZWFrcG9pbnRzKGZvcm11bGEsIGRhdGE9dGVtcF93aWtpcGVkaWEsaD1oKQp0ZW1wX3dpa2lwZWRpYSR5X2hhdCA8LSBmaXR0ZWQudmFsdWVzKGJwX3dpa2lwZWRpYSkKdGVtcF93aWtpcGVkaWEkZ3JvdXBzIDwtIDA7IHRlbXBfd2lraXBlZGlhJGdyb3Vwc1ticF93aWtpcGVkaWEkYnJlYWtwb2ludHMrMV0gPC0gMSA7IHRlbXBfd2lraXBlZGlhJGdyb3VwcyA8LSBjdW1zdW0odGVtcF93aWtpcGVkaWEkZ3JvdXBzKSsxCgoKdGVtcF9lY2RjIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iZWNkYyIpCmJwX2VjZGMgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX2VjZGMsaD1oKQp0ZW1wX2VjZGMkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9lY2RjKQp0ZW1wX2VjZGMkZ3JvdXBzIDwtIDA7IHRlbXBfZWNkYyRncm91cHNbYnBfZWNkYyRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF9lY2RjJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9lY2RjJGdyb3VwcykrMQoKdGVtcF93aG8gPC0gdGVtcCAlPiUgZmlsdGVyKGRhdGFzZXQ9PSJ3aG8iKQpicF93aG8gPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX3dobyxoPWgpCnRlbXBfd2hvJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMoYnBfd2hvKQp0ZW1wX3dobyRncm91cHMgPC0gMDsgdGVtcF93aG8kZ3JvdXBzW2JwX3dobyRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF93aG8kZ3JvdXBzIDwtIGN1bXN1bSh0ZW1wX3dobyRncm91cHMpKzEKCgp0ZW1wX21ldGFiaW90YSA8LSB0ZW1wICU+JSBmaWx0ZXIoZGF0YXNldD09Im1ldGFiaW90YSIpCmJwX21ldGFiaW90YSA8LSBicmVha3BvaW50cyhmb3JtdWxhLCBkYXRhPXRlbXBfbWV0YWJpb3RhLGg9aCkKdGVtcF9tZXRhYmlvdGEkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9tZXRhYmlvdGEpCnRlbXBfbWV0YWJpb3RhJGdyb3VwcyA8LSAwOyB0ZW1wX21ldGFiaW90YSRncm91cHNbYnBfbWV0YWJpb3RhJGJyZWFrcG9pbnRzKzFdIDwtIDEgOyB0ZW1wX21ldGFiaW90YSRncm91cHMgPC0gY3Vtc3VtKHRlbXBfbWV0YWJpb3RhJGdyb3VwcykrMQoKdGVtcF9iaW5nIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iYmluZyIpCmJwX2JpbmcgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX2JpbmcsaD1oKSAjdGhpcyBmYWlscyBiYyB0b28gZmV3CmxtX2JpbmcgPC1sbShmb3JtdWxhLCBkYXRhPXRlbXBfYmluZykKdGVtcF9iaW5nJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMobG1fYmluZykKdGVtcF9iaW5nJGdyb3VwcyA8LTEKCnRlbXBfZGYgPC0gYmluZF9yb3dzKHRlbXBfZWNkYywgdGVtcF9tZXRhYmlvdGEsIHRlbXBfYmluZywgdGVtcF93aG8sIHRlbXBfd2lraXBlZGlhKSAlPiUgCiAgICAgICAgICAgIGFycmFuZ2UoZGF0YXNldCxkYXRlX2FzZGF0ZSkgJT4lIAogICAgICAgICAgIG11dGF0ZShncm91cHM9cGFzdGUoZGF0YXNldCxncm91cHMpKQoKdGVtcF9kZjIgPC0gYmluZF9yb3dzKHRlbXBfZWNkYywgdGVtcF9tZXRhYmlvdGEsIHRlbXBfYmluZywgdGVtcF93aG8sIHRlbXBfd2lraXBlZGlhKSAlPiUgCiAgICAgICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICAgZ3JvdXBfYnkoZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgIHN1bW1hcmlzZSh5X2hhdF9tZWFuPW1lYW4oeV9oYXQsIG5hLnJtPVQpKSAlPiUKICAgICAgICAgICAgbXV0YXRlKGdyb3Vwcz05OSkKCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSkgKwogICBnZW9tX2xpbmUoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXBzKSkgKwogICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJDaGluYSAoUTE0OCkgQ29uZmlybWVkIikKICAgI2dlb21fdmxpbmUoeGludGVyY2VwdD1icCRicmVha3BvaW50cykKCgojSW5kaWEKIyJRNjY4Igp0ZW1wIDwtIGxoc19sb25nX2NsZWFuICU+JSBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgZmlsdGVyKHdpa2lkYXRhX2lkICVpbiUgIlE2NjgiKSAlPiUgCiAgICAgICAgZ3JvdXBfYnkoZGF0YXNldCwgZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgc3VtbWFyaXNlKGNvbmZpcm1lZD1tYXgoY29uZmlybWVkLCBuYS5ybT1UKSApICU+JSAjdGhpcyBpcyBhIHByb2JsZW0gZHVwZXMgd2l0aCB0aGUgc2FtZSBkYXRlICAjdGhpcyBmaXhlcyBhIGxvdCBvZiB0aGluZ3MgYnV0IHdlIG5lZWQgdG8gZmlndXJlIG91dCB0aGUgb3JpZ2luIG9mIHRoaXMgcHJvYmxlbQogICAgICAgIHVuZ3JvdXAoKSAlPiUKICAgICAgICBtdXRhdGUoY29uZmlybWVkX2xvZz1sb2coY29uZmlybWVkKzEpKSAlPiUgCiAgICAgICAgbXV0YXRlKGRhdGVfcmFuaz0gYXMubnVtZXJpYyhkYXRlX2FzZGF0ZSkgLSBtaW4oYXMubnVtZXJpYyhkYXRlX2FzZGF0ZSkpKSAgCnRhYmxlKHRlbXAkZGF0YXNldCkKCnRlbXBfY292aWQxOWluZGlhIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iY292aWQxOWluZGlhIikKYnBfY292aWQxOWluZGlhIDwtIGJyZWFrcG9pbnRzKGZvcm11bGEsIGRhdGE9dGVtcF9jb3ZpZDE5aW5kaWEsaD1oKQp0ZW1wX2NvdmlkMTlpbmRpYSR5X2hhdCA8LSBmaXR0ZWQudmFsdWVzKGJwX2NvdmlkMTlpbmRpYSkKdGVtcF9jb3ZpZDE5aW5kaWEkZ3JvdXBzIDwtIDA7IHRlbXBfY292aWQxOWluZGlhJGdyb3Vwc1ticF9jb3ZpZDE5aW5kaWEkYnJlYWtwb2ludHMrMV0gPC0gMSA7IHRlbXBfY292aWQxOWluZGlhJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9jb3ZpZDE5aW5kaWEkZ3JvdXBzKSsxCgp0ZW1wX3dpa2lwZWRpYSA8LSB0ZW1wICU+JSBmaWx0ZXIoZGF0YXNldD09Indpa2lwZWRpYSIpCmJwX3dpa2lwZWRpYSA8LSBicmVha3BvaW50cyhmb3JtdWxhLCBkYXRhPXRlbXBfd2lraXBlZGlhLGg9aCkKdGVtcF93aWtpcGVkaWEkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF93aWtpcGVkaWEpCnRlbXBfd2lraXBlZGlhJGdyb3VwcyA8LSAwOyB0ZW1wX3dpa2lwZWRpYSRncm91cHNbYnBfd2lraXBlZGlhJGJyZWFrcG9pbnRzKzFdIDwtIDEgOyB0ZW1wX3dpa2lwZWRpYSRncm91cHMgPC0gY3Vtc3VtKHRlbXBfd2lraXBlZGlhJGdyb3VwcykrMQoKdGVtcF9DU1NFIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iQ1NTRSIpCmJwX0NTU0UgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX0NTU0UsaD1oKQp0ZW1wX0NTU0UkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9DU1NFKQp0ZW1wX0NTU0UkZ3JvdXBzIDwtIDA7IHRlbXBfQ1NTRSRncm91cHNbYnBfQ1NTRSRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF9DU1NFJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9DU1NFJGdyb3VwcykrMQoKdGVtcF9lY2RjIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iZWNkYyIpCmJwX2VjZGMgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX2VjZGMsaD1oKQp0ZW1wX2VjZGMkeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9lY2RjKQp0ZW1wX2VjZGMkZ3JvdXBzIDwtIDA7IHRlbXBfZWNkYyRncm91cHNbYnBfZWNkYyRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF9lY2RjJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9lY2RjJGdyb3VwcykrMQoKdGVtcF93aG8gPC0gdGVtcCAlPiUgZmlsdGVyKGRhdGFzZXQ9PSJ3aG8iKQpicF93aG8gPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX3dobyxoPWgpCnRlbXBfd2hvJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMoYnBfd2hvKQp0ZW1wX3dobyRncm91cHMgPC0gMDsgdGVtcF93aG8kZ3JvdXBzW2JwX3dobyRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF93aG8kZ3JvdXBzIDwtIGN1bXN1bSh0ZW1wX3dobyRncm91cHMpKzEKCnRlbXBfbWV0YWJpb3RhIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0ibWV0YWJpb3RhIikKYnBfbWV0YWJpb3RhIDwtIGJyZWFrcG9pbnRzKGZvcm11bGEsIGRhdGE9dGVtcF9tZXRhYmlvdGEsaD1oKQp0ZW1wX21ldGFiaW90YSR5X2hhdCA8LSBmaXR0ZWQudmFsdWVzKGJwX21ldGFiaW90YSkKdGVtcF9tZXRhYmlvdGEkZ3JvdXBzIDwtIDA7IHRlbXBfbWV0YWJpb3RhJGdyb3Vwc1ticF9tZXRhYmlvdGEkYnJlYWtwb2ludHMrMV0gPC0gMSA7IHRlbXBfbWV0YWJpb3RhJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9tZXRhYmlvdGEkZ3JvdXBzKSsxCgp0ZW1wX2JpbmcgPC0gdGVtcCAlPiUgZmlsdGVyKGRhdGFzZXQ9PSJiaW5nIikKYnBfYmluZyA8LSBicmVha3BvaW50cyhmb3JtdWxhLCBkYXRhPXRlbXBfYmluZyxoPWgpICN0aGlzIGZhaWxzIGJjIHRvbyBmZXcKbG1fYmluZyA8LWxtKGZvcm11bGEsIGRhdGE9dGVtcF9iaW5nKQp0ZW1wX2JpbmckeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhsbV9iaW5nKQp0ZW1wX2JpbmckZ3JvdXBzIDwtMQoKdGVtcF9kZiA8LSBiaW5kX3Jvd3ModGVtcF9jb3ZpZDE5aW5kaWEsIHRlbXBfd2lraXBlZGlhLCB0ZW1wX0NTU0UsIHRlbXBfZWNkYywgdGVtcF93aG8sIHRlbXBfbWV0YWJpb3RhLCB0ZW1wX2JpbmcpICU+JSAKICAgICAgICAgICAgYXJyYW5nZShkYXRhc2V0LGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgICAgbXV0YXRlKGdyb3Vwcz1wYXN0ZShkYXRhc2V0LGdyb3VwcykpCgp0ZW1wX2RmMiA8LSBiaW5kX3Jvd3ModGVtcF9jb3ZpZDE5aW5kaWEsIHRlbXBfd2lraXBlZGlhLCB0ZW1wX0NTU0UsIHRlbXBfZWNkYywgdGVtcF93aG8sIHRlbXBfbWV0YWJpb3RhLCB0ZW1wX2JpbmcpICU+JSAKICAgICAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lIAogICAgICAgICAgICBncm91cF9ieShkYXRlX2FzZGF0ZSkgJT4lCiAgICAgICAgICAgICAgc3VtbWFyaXNlKHlfaGF0X21lYW49bWVhbih5X2hhdCwgbmEucm09VCkpICU+JQogICAgICAgICAgICBtdXRhdGUoZ3JvdXBzPTk5KQoKZ2dwbG90KCkgKyAKICAgZ2VvbV9wb2ludChkYXRhPXRlbXBfZGYsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZF9sb2csIGNvbG9yPWRhdGFzZXQpLCBhbHBoYT0uMykgKwogICBnZW9tX2xpbmUoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdCwgY29sb3I9ZGF0YXNldCwgZ3JvdXA9Z3JvdXBzKSkgKwogICAjZ2VvbV9saW5lKGRhdGE9dGVtcF9kZjIsIGFlcyh4PWRhdGVfYXNkYXRlLCB5PXlfaGF0X21lYW4pLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIHRoZW1lX2J3KCkgKwogICBnZ3RpdGxlKCJJbmRpYSAoUTY2OCkgQ29uZmlybWVkIikKCgojRmxvcmlkYQojUTgxMgp0ZW1wIDwtIGxoc19sb25nX2NsZWFuICU+JSBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUgCiAgICAgICAgZmlsdGVyKHdpa2lkYXRhX2lkICVpbiUgIlE4MTIiKSAlPiUgCiAgICAgICAgZ3JvdXBfYnkoZGF0YXNldCwgZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgc3VtbWFyaXNlKGNvbmZpcm1lZD1tYXgoY29uZmlybWVkLCBuYS5ybT1UKSApICU+JSAjdGhpcyBpcyBhIHByb2JsZW0gZHVwZXMgd2l0aCB0aGUgc2FtZSBkYXRlICAjdGhpcyBmaXhlcyBhIGxvdCBvZiB0aGluZ3MgYnV0IHdlIG5lZWQgdG8gZmlndXJlIG91dCB0aGUgb3JpZ2luIG9mIHRoaXMgcHJvYmxlbQogICAgICAgIHVuZ3JvdXAoKSAlPiUKICAgICAgICBtdXRhdGUoY29uZmlybWVkX2xvZz1sb2coY29uZmlybWVkKzEpKSAlPiUKICAgICAgICBtdXRhdGUoZGF0ZV9yYW5rPSBhcy5udW1lcmljKGRhdGVfYXNkYXRlKSAtIG1pbihhcy5udW1lcmljKGRhdGVfYXNkYXRlKSkpICAKdGFibGUodGVtcCRkYXRhc2V0KQoKdGVtcF9jb3ZpZHRyYWNraW5nIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0iY292aWR0cmFja2luZyIpCmJwX2NvdmlkdHJhY2tpbmcgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX2NvdmlkdHJhY2tpbmcsaD1oKQp0ZW1wX2NvdmlkdHJhY2tpbmckeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhicF9jb3ZpZHRyYWNraW5nKQp0ZW1wX2NvdmlkdHJhY2tpbmckZ3JvdXBzIDwtIDA7IHRlbXBfY292aWR0cmFja2luZyRncm91cHNbYnBfY292aWR0cmFja2luZyRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF9jb3ZpZHRyYWNraW5nJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9jb3ZpZHRyYWNraW5nJGdyb3VwcykrMQoKdGVtcF93aWtpcGVkaWEgPC0gdGVtcCAlPiUgZmlsdGVyKGRhdGFzZXQ9PSJ3aWtpcGVkaWEiKQpicF93aWtpcGVkaWEgPC0gYnJlYWtwb2ludHMoZm9ybXVsYSwgZGF0YT10ZW1wX3dpa2lwZWRpYSxoPWgpCnRlbXBfd2lraXBlZGlhJHlfaGF0IDwtIGZpdHRlZC52YWx1ZXMoYnBfd2lraXBlZGlhKQp0ZW1wX3dpa2lwZWRpYSRncm91cHMgPC0gMDsgdGVtcF93aWtpcGVkaWEkZ3JvdXBzW2JwX3dpa2lwZWRpYSRicmVha3BvaW50cysxXSA8LSAxIDsgdGVtcF93aWtpcGVkaWEkZ3JvdXBzIDwtIGN1bXN1bSh0ZW1wX3dpa2lwZWRpYSRncm91cHMpKzEKCnRlbXBfbWV0YWJpb3RhIDwtIHRlbXAgJT4lIGZpbHRlcihkYXRhc2V0PT0ibWV0YWJpb3RhIikKYnBfbWV0YWJpb3RhIDwtIGJyZWFrcG9pbnRzKGZvcm11bGEsIGRhdGE9dGVtcF9tZXRhYmlvdGEsaD1oKQp0ZW1wX21ldGFiaW90YSR5X2hhdCA8LSBmaXR0ZWQudmFsdWVzKGJwX21ldGFiaW90YSkKdGVtcF9tZXRhYmlvdGEkZ3JvdXBzIDwtIDA7IHRlbXBfbWV0YWJpb3RhJGdyb3Vwc1ticF9tZXRhYmlvdGEkYnJlYWtwb2ludHMrMV0gPC0gMSA7IHRlbXBfbWV0YWJpb3RhJGdyb3VwcyA8LSBjdW1zdW0odGVtcF9tZXRhYmlvdGEkZ3JvdXBzKSsxCgp0ZW1wX2JpbmcgPC0gdGVtcCAlPiUgZmlsdGVyKGRhdGFzZXQ9PSJiaW5nIikKYnBfYmluZyA8LSBicmVha3BvaW50cyhmb3JtdWxhLCBkYXRhPXRlbXBfYmluZyxoPWgpICN0aGlzIGZhaWxzIGJjIHRvbyBmZXcKbG1fYmluZyA8LWxtKGZvcm11bGEsIGRhdGE9dGVtcF9iaW5nKQp0ZW1wX2JpbmckeV9oYXQgPC0gZml0dGVkLnZhbHVlcyhsbV9iaW5nKQp0ZW1wX2JpbmckZ3JvdXBzIDwtMQoKdGVtcF9kZiA8LSBiaW5kX3Jvd3ModGVtcF9jb3ZpZHRyYWNraW5nLCB0ZW1wX3dpa2lwZWRpYSwgdGVtcF9tZXRhYmlvdGEsIHRlbXBfYmluZykgJT4lIAogICAgICAgICAgICBhcnJhbmdlKGRhdGFzZXQsZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICBtdXRhdGUoZ3JvdXBzPXBhc3RlKGRhdGFzZXQsZ3JvdXBzKSkKCnRlbXBfZGYyIDwtIGJpbmRfcm93cyh0ZW1wX2NvdmlkdHJhY2tpbmcsIHRlbXBfd2lraXBlZGlhLCB0ZW1wX21ldGFiaW90YSwgdGVtcF9iaW5nKSAlPiUgCiAgICAgICAgICAgIGFycmFuZ2UoZGF0ZV9hc2RhdGUpICU+JSAKICAgICAgICAgICAgZ3JvdXBfYnkoZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgIHN1bW1hcmlzZSh5X2hhdF9tZWFuPW1lYW4oeV9oYXQsIG5hLnJtPVQpKSAlPiUKICAgICAgICAgICAgbXV0YXRlKGdyb3Vwcz05OSkKCmdncGxvdCgpICsgCiAgIGdlb21fcG9pbnQoZGF0YT10ZW1wX2RmLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT1jb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjMpICsKICAgZ2VvbV9saW5lKGRhdGE9dGVtcF9kZiwgYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9eV9oYXQsIGNvbG9yPWRhdGFzZXQsIGdyb3VwPWdyb3VwcykpICsKICAgI2dlb21fbGluZShkYXRhPXRlbXBfZGYyLCBhZXMoeD1kYXRlX2FzZGF0ZSwgeT15X2hhdF9tZWFuKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICB0aGVtZV9idygpICsKICAgZ2d0aXRsZSgiRmxvcmlkYSAoUTgxMikgQ29uZmlybWVkIikKCmBgYAoKCgpgYGB7ciwgZXZhbD1GLCBlY2hvPUYsd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLGVycm9yPUZBTFNFfQojQXMgd2FzIHRoaXMgcGFydAojICMgUTY2OCAgUTE2ODYxICBRMTQ4ICBRMzAgUTE0OCBRMTY4NjEgUTMwCnRlbXAgPC0gdGVtcF9kZiAlPiUgZmlsdGVyKHdpa2lkYXRhX2lkPT0iUTE0OCIpICU+JSBtdXRhdGUoZGF0ZV9hc251bWVyaWM9YXMubnVtZXJpYyhkYXRlX2FzZGF0ZSkpCnRlbXAgJT4lIGdncGxvdCgpICsgZ2VvbV9wb2ludChhZXMoZGF0ZV9hc2RhdGUsY29uZmlybWVkX2xvZykpICArIGZhY2V0X3dyYXAofmRhdGFzZXQpICMrIGdlb21fcG9pbnQoYWVzKGRhdGVfYXNkYXRlLGNvbmZpcm1lZF9sb2dfeV9oYXQpLCBjb2xvcj0iYmx1ZSIpCgojbGlicmFyeShycGFydCkKI3J0IDwtIHJwYXJ0KGNvbmZpcm1lZF9sb2cgfiAxICsgZGF0ZV9hc2RhdGUgLCBkYXRhPXRlbXApCiN0ZW1wJHlfaGF0IDwtIHByZWRpY3QoIHJ0LCBuZXdkYXRhPXRlbXAgKQoKI3RlbXAkZGF0YXNldCA8LSBhcy5mYWN0b3IodGVtcCRkYXRhc2V0KQojZm1CSCA8LSBtb2IoY29uZmlybWVkX2xvZyB+IDEgKyB0ICsgSSh0XjIpICsgSSh0XjMpIHwgdCArIGRhdGFzZXQsIGNvbnRyb2wgPSBtb2JfY29udHJvbChtaW5zcGxpdCA9IDMpLCBkYXRhID0gdGVtcCwgIG1vZGVsID0gbGluZWFyTW9kZWwpICN0aGlzIGZpdHMgYSBwaWVjZXdpc2UgbGluZWFyIHRvIGVhY2ggZGF0YXNldCAjaGF2ZSB0byB1c2UgdCwgZG9lc24ndCBsaWtlIGRhdGEgb2JqZWN0cwojcGxvdChmbUJIKQojY29lZihmbUJIKQojdGVtcCR5X2hhdCA8LSBwcmVkaWN0KCBmbUJILCBuZXdkYXRhPXRlbXAgKQoKI1RoZSB0cmljayBpcyBmaXR0aW5nIG9ubHkgdG8gb25lIGRhdGFzZXQgYXQgYSB0aW1lCnRlbXBfbGlzdCA8LSBsaXN0KCkKZm9yKCBkIGluIHRlbXAkZGF0YXNldCAlPiUgdW5pcXVlKCkgKXsKICB0ZW1wdGVtcCA8LSB0ZW1wICU+JSBmaWx0ZXIoZGF0YXNldD09ZCkKICBmbUJIIDwtIG1vYihjb25maXJtZWRfbG9nIH4gMSArIGRhdGVfYXNudW1lcmljICAgIHwgZGF0ZV9hc251bWVyaWMgLCBjb250cm9sID0gbW9iX2NvbnRyb2wobWluc3BsaXQgPSAzLCBhbHBoYT0uMiksIGRhdGEgPSB0ZW1wdGVtcCwgIG1vZGVsID0gbGluZWFyTW9kZWwpICAjICsgSShkYXRlX2FzbnVtZXJpY14yKSAgICAgKyBJKHReMykgICMgKyBJKHReMikgKyBJKHReMykgKyBJKHReNCkgKyBJKHReMikgCiAgdGVtcHRlbXAkeV9oYXQgPC0gcHJlZGljdCggZm1CSCwgbmV3ZGF0YT10ZW1wdGVtcCAsIHR5cGUgPSBjKCJyZXNwb25zZSIpICkKICB0ZW1wdGVtcCRncm91cF9udW1iZXIgPC0gIHByZWRpY3QoIGZtQkgsIG5ld2RhdGE9dGVtcHRlbXAgLCB0eXBlID0gYygibm9kZSIpKQogIHRlbXB0ZW1wIDwtIHRlbXB0ZW1wICU+JSBncm91cF9ieShncm91cF9udW1iZXIpICU+JSBhcnJhbmdlKGRhdGVfYXNudW1lcmljKSAlPiUgbXV0YXRlKHNsb3BlPXRzaWJibGU6OmRpZmZlcmVuY2UoeV9oYXQpKSAlPiUgZmlsbChzbG9wZSwgLmRpcmVjdGlvbj0idXAiKSAlPiUgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHBlcmNlbnRfY2hhbmdlID0gcm91bmQoKGV4cChzbG9wZSktMSkqMTAwLDIpKSAKCiAgdGVtcF9saXN0W1tkXV0gPC0gdGVtcHRlbXAKfQoKY29tYmluZWQgPC0gYmluZF9yb3dzKHRlbXBfbGlzdCkgCnAwIDwtIGNvbWJpbmVkICU+JQogICAgIG11dGF0ZShncm91cD1wYXN0ZSh3aWtpZGF0YV9pZCwgZGF0YXNldCwgZ3JvdXBfbnVtYmVyKSkgJT4lCiAgICAgZ2dwbG90KCkgKyBnZW9tX3BvaW50KGFlcyhkYXRlX2FzZGF0ZSxjb25maXJtZWRfbG9nLCBjb2xvcj1kYXRhc2V0KSwgYWxwaGE9LjUpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZShhZXMoZGF0ZV9hc2RhdGUseV9oYXQsIGdyb3VwPWdyb3VwKSwgY29sb3I9ImJsdWUiLCBhbHBoYT0xKSArIGZhY2V0X3dyYXAofmRhdGFzZXQpICsgdGhlbWVfYncoKSAjaXQgc2hpdHMgdGhlIGJlZCBpbiB0aGF0IGJpZyBnYXAgaW4gd2lraXBlZGlhCgpmbUJIX3Nsb3BlIDwtIG1vYihjb25maXJtZWRfbG9nIH4gMSAgIHwgZGF0ZV9hc251bWVyaWMgLCBjb250cm9sID0gbW9iX2NvbnRyb2wobWluc3BsaXQgPSAzLCBhbHBoYT0uMSksIGRhdGEgPSBjb21iaW5lZCwgIG1vZGVsID0gbGluZWFyTW9kZWwpICAjaXQgZG9lc24ndCB3YW50IHRvIGRvIApydDEgPC0gcnBhcnQoZm9ybXVsYSA9IHBlcmNlbnRfY2hhbmdlIH4gZGF0ZV9hc251bWVyaWMsIGRhdGE9Y29tYmluZWQpCmNvbWJpbmVkJHBlcmNlbnRfY2hhbmdlX3lfaGF0IDwtICBwcmVkaWN0KHJ0MSwgbmV3ZGF0YT1jb21iaW5lZCkKI2NvbWJpbmVkJHNsb3BlX3lfaGF0IDwtIHByZWRpY3QoIGZtQkhfc2xvcGUsIG5ld2RhdGE9Y29tYmluZWQgICwgdHlwZSA9IGMoInJlc3BvbnNlIikgKQojY29tYmluZWQkZ3JvdXBfbnVtYmVyIDwtIHByZWRpY3QoIGZtQkhfc2xvcGUsIG5ld2RhdGE9Y29tYmluZWQgICwgdHlwZSA9IGMoIm5vZGUiKSApCgpwMSA8LSBjb21iaW5lZCAlPiUKICAgICBtdXRhdGUoZ3JvdXA9cGFzdGUod2lraWRhdGFfaWQsIGRhdGFzZXQsIGdyb3VwX251bWJlcikpICU+JQogICAgIGdncGxvdCgpICsgZ2VvbV9wb2ludChhZXMoZGF0ZV9hc2RhdGUsY29uZmlybWVkX2xvZywgY29sb3I9ZGF0YXNldCksIGFscGhhPS41KSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoYWVzKGRhdGVfYXNkYXRlLHlfaGF0LCBncm91cD1ncm91cCwgY29sb3I9ZGF0YXNldCksIGFscGhhPS4xKSArIHRoZW1lX2J3KCkgKyBmYWNldF93cmFwKH5kYXRhc2V0KSMgICNpdCBzaGl0cyB0aGUgYmVkIGluIHRoYXQgYmlnIGdhcCBpbiB3aWtpcGVkaWEKCgpwMiA8LSBjb21iaW5lZCAlPiUgZ2dwbG90KCkgKyBnZW9tX3BvaW50KGFlcyhkYXRlX2FzZGF0ZSxwZXJjZW50X2NoYW5nZV95X2hhdCwgY29sb3I9ZGF0YXNldCksIGFscGhhPS41KSArIAogICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhkYXRlX2FzZGF0ZSxwZXJjZW50X2NoYW5nZV95X2hhdCksIGNvbG9yPSJibGFjayIsIGFscGhhPTEpICsgdGhlbWVfYncoKSArIGZhY2V0X3dyYXAofmRhdGFzZXQpICMrIGZhY2V0X3dyYXAofmRhdGFzZXQpICNpdCBzaGl0cyB0aGUgYmVkIGluIHRoYXQgYmlnIGdhcCBpbiB3aWtpcGVkaWEKCnAxIC8gcDIKCgpgYGAKCgo=